마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 통신처리시 구조에 대한 질문 코드 첨부해서 다시 올립니다.

0 추천

현재 상황은 아이템을 구입하는데

먼저 서버로 구매하고자하는 캐쉬의 해당 가격만큼을 전송하여 내 캐쉬에서 차감을 서버상에서 실시하며

해당 작업이 성공적으로 완료된 경우 특정 리턴값을 받와서 그 값을 비교한 "이후"에 뒤의 작업들을 진행하려 합니다.

먼저 쿠키(캐쉬)를 차감하는 로직입니다.

두 로직은 동일한 클래스에 선언되어있습니다.

/**
* 요약 : 컨텐츠의 쿠키(캐쉬)정보를 서버로 보내어 차감처리한 후 결과값을 받아온다.
* @param contentsCookie 해당 컨텐츠의 필요 쿠키수
* @return 성공 실패여부 리턴
*/
private void cookieConsume(final int contentsCookie, final OnCookieConsumeListener listener) {
    Runnable cookieConsumeRunnable = new Runnable() {
    @Override
       public void run() {
       // TODO Auto-generated method stub
             if(LoginUserData.sCookie > contentsCookie) { //현재 가진 쿠키가 컨텐츠 가격보다 높다.
           //쿠키 차감 통신 처리 (아직 세부 로직은 작성하지 않았습니다.)
       boolean result = .... 
       listener.onCookieConsumeResult(result); //결과값 리턴
}else { //쿠키가 부족할 경우 fasle 리턴
       listener.onCookieConsumeResult(result); //결과값 리턴
  }
 }
};
Thread th = new Thread(cookieConsumeRunnable);
th.start();
}
 
위의 로직을 이렇게 사용합니다.
 
 
case R.id.contents_popup_bottom_play_Button :
    cookieConsume(10, new OnCookieConsumeListener() {
    @Override
        public void onCookieConsumeResult(final boolean result) {
        // TODO Auto-generated method stub
           if(result == true) { //결과값이 성공이면 다음 처리
           //콘텐츠 재생
 
            }else {
 
             }
       }
});
break;

위와 같이 로직을 구성하고 있습니다.

인터페이스 콜백을 이용해서 받게끔 처리하였는데요.

public interface OnCookieConsumeListener {
    public void onCookieConsumeResult(boolean result);
}
 
그런데 위와같이 처리를 하면 결과값을 받고나서 UI 작업을 하려니 Runnable Thread에 종속된 상황이라 UI업데이트를 하자니 아래와 같이 또 RunOnUiThread를 사용해서 또다시 Runnable이 중첩되어 버리는데 동작상의 문제는 없는데
뭔가 더 좋은 방법이 있을거 같아 이렇게 조언을 구합니다.
 
case R.id.contents_popup_bottom_play_Button :
    cookieConsume(10, new OnCookieConsumeListener() {
    @Override
        public void onCookieConsumeResult(final boolean result) {
        // TODO Auto-generated method stub
           if(result == true) { //결과값이 성공이면 다음 처리
                     getActivity().runOnUiThread(new Runnable() {
                      @Override
                      public void run() {
                      // TODO Auto-generated method stub
                             //UI처리
                             //콘텐츠 재생
                              }
                     });
            }else {
 
             }
       }
});
 
갸아악 (21,260 포인트) 님이 2014년 10월 15일 질문

2개의 답변

0 추천
핸들러 핸들러가 답입니다.
ThisPlus (46,920 포인트) 님이 2014년 10월 15일 답변
;;;;;;;;;;;;;;;;;;;;;;
0 추천
Async한 작업의 특성상 자바에서 콜백구조는 어쩔 수 없구요.

Thread보다는 AsyncTask를 쓰세요. AsyncTask는 썡 Thread를 쓰는 것에 비해 다음과 같은 이점이 있습니다.(물론 Thread로도 아래와 같은 것을 구형할 수 있지만 이미 만들어 놓은 것을 쓰는 게 낫죠)

* 내부적으로 Thread pool을 이용하므로 여러번 사용하더라도 귀중한 리소스인 thread를 불필요하게 만들지 않습니다.

* 백그라운드 실행이 종료되고 그 결과를 불러주는 함수인 postExecute를 main thread에서 호출합니다. 님 코드처럼 runOnUiThread를 호출할 필요 없습니다.

* 강제로 sync로도 호출이 가능합니다. 즉 백그라운드 작업이 끝날때까지 main thread를 대기시킬 수도 있습니다.
레오나 (3,290 포인트) 님이 2014년 10월 15일 답변
친절하고 상세한 답변 진심으로 감사드립니다.
정말 복받으실거에요.
많이 배웁니다.^^
그런데 한가지 궁금한게 있습니다.
AsyncTask에서 작업을 빼서 처리하면 좋긴 할텐데
만약 Activity에 선언되어 있는 멤버변수, 혹은 View객체들에 접근하려면
완전 독립되어 있는 AsyncTask에서는 어찌 접근해야될까요?
전 이 접근이 용이할거 같아 Activity내부에서 Runnable 처리를 하였거든요.
음.. AsyncTask를 상속받아 inner class 형태로 만들어 쓰면 되겠죠. 위에서 님이 Runnable을 implements해 inner class로 만든 것과 완전히 같은 형태로 쓰면 됩니다.

즉,

private String m_member;
interface Callback {
    void onFinish(String result);
}

private void doAsyncByThread(final Callback cb) {
    new Thread(new Runnable() {
        public void run() {
            final String result = doNetworkOperation(m_member);
            runOnUiThread(new Runnable() {
                public void run() {
                    cb.onFinish(result);
                }
            };
        }
    }.start();
}

요 방식을,

private void doAsyncByAsyncTask(final Callback cb) {
    new AsyncTask<Void, Void, String>() {
        public String doInBackground() {
            return doNetworkOperation(m_member);
        }

        public void postExecute(String result) {
            cb.onFinish(result);
        }
    }.execute();
}

이렇게 바꿀 수 있습니다.
...