안드로이드 공부하면서 블러그를 보니까 AsyncTask를 상당히 많이 사용하는거 같았다.

ios 개발자다 보니 AsyncTask 단점을 알면서도 왜 사용하는지 좀 의아했지만 Deprecated 된걸 보니 어느정도? 이해는 간다.

 

그래도 기본 사용 방법은 알아야 될듯 해서 블러그로 남긴다.

참고자료 : https://velog.io/@haero_kim/Android-AsyncTask-%EA%B0%80-%EB%96%A0%EB%82%98%EA%B0%84-%EC%9D%B4%EC%9C%A0

 

[Android] AsyncTask 가 떠나간 이유

우리의 옛사랑 AsyncTask 의 사인 파헤쳐보기

velog.io

 

  1. 메모리 릭
    화면이 회전할 때 액티비티는 종료되었다가 새롭게 생성된다. 이 경우 AsyncTask 가 계속 중첩되어 실행될 수가 있다. 새로 생성된 액티비티는 완전히 다른 인스턴스인데, AsyncTask 가 실행되고 있던 와중에 화면 회전이 일어난 거라면 기존 액티비티조차 메모리에서 해제되지 않는다. 이는 OutOfMemory 에러를 뿜을 가능성이 농후하다.
  1. 순차적으로 실행되기 때문에 속도가 저하될 수 있음
  1. Fragment 에서 AsyncTask 를 실행할 경우
    Fragment 에서 AsyncTask 를 실행하고 뒤로가기 키를 통해 액티비티를 종료하면, Fragment 가 Activity 와 분리되면서 getContext(), getActivity() 등이 null 을 반환하게 되어 onPostExecute() 에서 NullPointerException 이 발생하게 된다.
  1. 취소 메소드만 있고, onError() 와 같은 예외처리 메소드 없음
  1. AsyncTask 병렬 실행 시 doInBackground() 의 실행순서가 보장되지 않음
    안드로이드 버전이 올라가면서, 기본 동작이 순차 실행으로 바뀌었기 때문에 플랫폼의 버전에 따라 일관되지 않은 동작을 야기할 수 있는 점이 문제다.

 

excute()로 실행해보니 doInBackground가 바로 실행 되지 않고 지연되서 실행이 되서 확인해 보니 아래와 같이 excuteOnExecutor로 실행해야 바로 동작 했다.

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB/*HONEYCOMB = 11*/) {
    backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
    backgroundTask.execute();
}

 

하지만 AsyncTask를 사용할 일은 없을것 같다. Runable, Thread로 동기화 해서 사용해도 충분할듯 하다.

public class TestBackgroundTask extends AsyncTask<Integer, Integer, Integer> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.d("TestBackgroundTask", "onPreExecute");
    }

    @Override
    protected Integer doInBackground(Integer... integers) {
        int result = 0;
        for(int i = 0 ; i < 100 ; i++) {
            result++;
            if (i % 10 == 0) {
                publishProgress(i);
            }
        }
        // return시 onPostExecute 호출됨
        return result;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        Log.d("TestBackgroundTask", "Progress : " + values[0] + "%");
    }

    @Override
    protected void onPostExecute(Integer integer) {
        super.onPostExecute(integer);
        Log.d("TestBackgroundTask", "Result : " + integer);
    }
}

 

실행

TestBackgroundTask backgroundTask = new TestBackgroundTask();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB/*HONEYCOMB = 11*/) {
    backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
    backgroundTask.execute();
}

+ Recent posts