바르고 뜨겁게

[안드로이드] AsyncTask 분리하기 , 서버통신 분리하기 본문

안드로이드

[안드로이드] AsyncTask 분리하기 , 서버통신 분리하기

RightHot 2019. 3. 28. 00:07

화면을 렌더링하는 Activity java에서 AsyncTask 처리를 할경우

  1. 처리 후 onPostExecute가 호출되는 시점을 관리하기가 까다롭다. EX) 서버 통신 후 TextView에 setText를 하는 경우 사용자가 화면을 이동하여 setText를 못하는 경우 앱이 죽는다.

  2. 같은 메서드라도 화면마다 호출해야 되기 때문에 유지보수에 어려움이 있다. EX) A화면에서 login 처리, B화면에서 login 처리, C화면 ... 일경우 수정이 일어나면 일일히 모든 Activity java에서 수정을 해야한다.

따라서 브로드캐스트 리시버를 이용한 아래와 같은 방법으로 서버 통신 로직을 분리 할 수 있다.


1. 렌더링할 Activity java 에서 브로드캐스트 리시버를 생성한다.

// 브로드 캐스트 리시버 옵저버 (서버 통신 후 로직 처리)
private BroadcastReceiver broadCastReceiver = new BroadcastReceiver() {
   @Override
   public void onReceive(Context contextIntent intent) {
       HashMap<StringString> result = (HashMap<StringString>intent.getSerializableExtra("result");
       String bcName = intent.getStringExtra("bcName");
       Log.d(TAG"브로드캐스트 수신 bcName: " + bcName);

       if ("m_app_version".equals(bcName)) {
           String rsp_code = result.get("RSP_CODE");

           if ("100".equals(rsp_code)) {

               // 화면 처리

          } else {
               CommonAlert.toastMsgLong(getText(R.string.error_msg_restart+ "(" + rsp_code + ")"mContext);
          }
      }  
  }
};


2. 렌더링할 Activity java 에서 리시버를 수신, 해제한다

@Override
protected void onCreate(Bundle savedInstanceState) {

  // SERVER_COMMNUNICATION 이름으로 정의된 브로드캐스트를 수신
  LocalBroadcastManager.getInstance(this).registerReceiver(broadCastReceivernew IntentFilter("SERVER_COMMNUNICATION"));
}

@Override
protected void onDestroy() {
   // 화면을 벗어나면 구독종료
   LocalBroadcastManager.getInstance(this).unregisterReceiver(broadCastReceiver);
   super.onDestroy();
}


3. 서버통신을 공통으로 담당할 class

public class ServerCommunication {
   private final static String SC_TAG = "ServerCommunication";

   private static void broadCastSend(Context getContextfinal String bcNamefinal HashMap resultMap) {
       Intent intent = new Intent("SERVER_COMMNUNICATION");
       intent.putExtra("result"resultMap);
       intent.putExtra("bcName"bcName);
       LocalBroadcastManager.getInstance(getContext).sendBroadcast(intent);
  }


   // ** 앱 버전 체크
   public static void m_app_version(final Context getContext) {
       final HashMap resultMap = new HashMap();

       AsyncTask<VoidVoidVoid> worker = new AsyncTask<VoidVoidVoid>() {
           String ACTION_METHOD = "- m_app_version() ";

           @Override
           protected void onPreExecute() {
               Log.d(SC_TAGACTION_METHOD + "시작");
               super.onPreExecute();
          }

           @Override
           protected Void doInBackground(Void... params) {
               
               // 통신로직 처리 ... 화면으로 전달할 데이터 SET
               resultMap.put("RSP_CODE"rsp_code);

               return null;
          }

           @Override
           protected void onPostExecute(Void result) {
               Log.d(SC_TAGACTION_METHOD + " onPostExecute RSP_CODE: " + rsp_code);
               
               // 구독중인 화면으로 데이터 전송
               broadCastSend(getContext"m_app_version"resultMap);
          }
      };
       worker.execute();
  }
}

이렇게 처리를 하면 onPostExecute가 호출되는 시점에 화면이 이동되더라도 이미 브로드캐스트리시버의 구독을 취소했기 때문에

1번과 같은 문제점이 발생하지 않는다.

또한 별도의 class에서 모든 로직이 분리되어 관리되기 때문에 해당 class에서 하나의 로직만 수정해주면

모든 class에 적용이 되어 유지보수가 편리하다.

Comments