android.os.AsyncTask는 시간이 오래 걸리는 작업을 백그라운드로 처리하기 위한 코드를 단순화해주는 유틸리티 클래스입니다. (AsyncTask에 대한 사용법은 http://tigerwoods.tistory.com/28 사이트에 친절히 설명되어있습니다.)

그런데 앱에서 AsyncTask를 이용하여 비슷비슷한 작업들을 처리하다보면 AsyncTask에 공통기능을 넣어야할 필요를 느끼게됩니다. 작업을 처리하는 동안 사용자에게 처리중임을 알리는 progress dialog를 띄운다든가, 처리중에 에러가 발생한 경우 에러 toast를 보여준다든가, 사용자가 취소키를 눌렀을 때 작업을 취소시키는 등의 기능이 주요 공통된 사항으로 들어갑니다.

추가된 기능
그래서 기존 AsyncTask에 몇가지 기능을 추가한 EnhancedAsyncTask를 만들어봤습니다.

AsyncTask와 다른 점은 다음과 같습니다.

1. Activity에 대한 약한 참조(weak reference) 유지
2. onPreExecute()에서 '작업처리중' 프로그레스 다이얼로그 자동 시작
3. onPostExecute()에서 프로그레스 다이얼로그 자동 종료
4. doInBackground()에서 에러발생시 프로그레스 다이얼로그 자동 종료 및 에러메시지 토스트보여줌
    - 참고로 doInBackground()에서 에러발생시 하위 클래스의 onPostExecute()는 실행되지 않음
5. '작업처리중' 프로그레스 다이얼로그에서 사용자가 취소키 누르면 onCancelled() 실행
6. onCancelled()에서 프로그레스 다이얼로그 자동 종료 및 작업취소 메시지 보여줌


EnhancedAsyncTask 사용법
EnhancedAsyncTask를 상속받아 생성자를 정의하고 doInBackground(WeakTarget, Params) 메소드를 구현합니다. 필요시 WeakTarget을 아규먼트로 받는 onPreExecute(), onPostExecute(), onCancelled() 메소드를 오버라이드합니다. 이렇게 구현한 EnhancedAsyncTask는 아래처럼 실행시킵니다.

MyLongTask task = new MyLongTask(this); //this는 Activity 인스턴스
task.execute(someParamObjects);

 
* 참고로 onPreExecute(), onPostExecute(), onCancelled() 메소드는 메인 UI쓰레드에서 실행되므로 UI 관련 작업이 가능하지만 doInBackground()는 별도의 쓰레드에서 실행되므로 직접적인 UI 작업은 불가합니다.

LoginTask 예제
다음 코드는 사용자가 입력한 ID/PW를 원격서버에 보내어 인증을 처리하는 작업을 구현한 예제입니다.
 

public class LoginTask extends EnhancedAsyncTask<LoginModel, Void, Boolean, LoginActivity> {
    public LoginTask(LoginActivity target) {
        super(target);
    }
 
    @Override
    protected Boolean doInBackground(LoginActivity target, LoginModel... params) {
        // ID/PW를 리모트 서버로 보내 원격으로 로그인 처리
        // return true or false;
    }

    @Override
    protected void onPostExecute(LoginActivity target, Boolean loginSuccess) {
        if (loginSuccess) {
            // 메인메뉴 화면 진입
        } else {
            // 로그인 실패 메시지 보여주고 로그인 화면 유지
        }
    }


액티비티에서는 아래처럼 LoginTask를 실행하면 됩니다.

 LoginModel loginModel = ...;
 LoginTask task = new LoginTask(this); //this는 LoginActivity 인스턴스
 task.execute(loginModel);


* 물론 EnhancedAsyncTask는 AsyncTask보다는 general하지 않기때문에 프로젝트에 따라서 적절히 수정을 가해야할 것입니다.
Posted by 에코지오
,