AsyncTask

똘이주인·2021년 8월 5일
0

AsyncTask 클래스는 안드로이드에서 요구하는 메인 스레드(Main Thread)와 작업 스레드의 분리 구조를 보다 쉽게 구현하도록 도와주는 추상 클래스

AsyncTask 주요 재정의 함수

안드로이드의 AsyncTask 생명주기 관리는 다섯 가지의 생명주기 함수들을 재정의함으로써 관리할 수 있습니다.

인자는 3 제네릭 타입 으로 정의, ParamsProgress, 그리고 Result 이며,

단계는 4단계로 정의

  1. onPreExecute: UI thread 에서 실행되고, Progress Bar를 띄울때
  2. doInBackground Background thread이고 onPreExecute() 호출된 다음
  3. onProgressUpdate UI thread에서 실행되고, publishProgress(Progress…)가 호출되면 실행. 주로 Progress Bar 갱신할 때 사용.
  4. onPostExecute UI thread에서 실행. 모든 백그라운 작업이 종료 후 호출됨.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called
            if (isCancelled()) break;
        }
        return totalSize;
    }

    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }

    protected void onPostExecute(Long result) {
        showDialog("Downloaded " + result + " bytes");
    }
}

// -------------------------------------------------------------------------------

new DownloadFilesTask().execute(url1, url2, url3);

가변인자 (varargs)

가변인자는 0 혹은 그 이상의 인자를 받을 수 있음을 나타낸다.

thisIsFunction(); // 가능
thisIsFunction("arg1"); //가능
thisIsFunction("arg1", "arg2", "arg3"); //가능
thisIsFunction(new String[]{"arg1", "arg2", "arg3"}); //가능

/*
	인자를 omit 하여도 성립하고, 1개 이상의 인자를 넘겨주거나,
	배열 형태로 넘겨 줄 수 있다. 하지만, 여기서 주의해야 할 점은,
	인자를 1개만 넘겨주어도 배열의 형태로 다뤄줘야 한다는 점
*/

// doInBackground 함수로 돌아가서, urls를 1개만 넘겨주었더라도,
protected Long doInBackground(URL... urls) {
    long totalSize =  Downloader.downloadFile(urls[0]);
    return totalSize;
}
/*배열로 처리해주어야만 한다.
	또한, varargs를 다른 parameter와 동시에 넘겨줄 경우
	varargs는 항상 나중에 자리해야만 한다.
*/

// -------------------------------------------------------------------------------

thisIsFunction(int n, String... strings) // 가능
thisIsFunction(String... strings, int n) // Error

AsyncTask 의 취소(cancel)

///AsyncTask는 cancel(boolean)을 통해 취소할 수 있다.

downloadTask.cancel(true);

AsyncTask가 취소되면, onPostExecute(Object)가 호출 되지 않고, 대신 onCancelled(Object)가 호출되게 되는데, 시점은 doInBackground(Object[])가 return 될 때이다.

Task가 cancel 되었을 때 최대한 빨리 Task가 cancelled에 대한 처리를 하게 하고 싶다면, isCancelled()를 doInBackground 함수 내에서 주기적으로 체크하게 해야한다.

추가적으로 주의해야 할 점

Android Developers의 공식 문서에는

onPreExecute()
onPostExecute(Result)
doInBackground(Params...)
onProgressUpdate(Progress...)

를 명시적으로 호출하지 말라고 한다.

또한, AsyncTask의 생성과 로드, execute() 함수 호출은 UI thread에서 실행되어야 하며,

task의 실행은 한 번만 호출되어야 한다고 명시하고 있다.

0개의 댓글