본문 바로가기

Android/Handler & AsyncTask

AsyncTask - android.os.AsyncTask

android.os.AsyncTask



원문링크 : AsyncTask


Class Overview



AsyncTask 는 UI 스레드를 적절하고 쉽게 사용할 수 있게 합니다. 이 클래스는 스레드핸들러를 정교하게 다루는 것 없이, 백그라운드 작업을 수행하고, UI 스레드에 결과를 퍼블리쉬 할 수 있게 합니다.


AsyncTask 는 스레드와 핸들러에 대한 헬퍼 클래스가 될 수 있도록 설계되어있으며, 제너릭 스레딩 프레임워크를 구성하지 않습니다. AsyncTask 는 (최대 몇초 밖에 안걸리는) 짧은 작업에 사용되어야합니다. 


오랫동안 스레드를 유지해야 하는 경우라면, 그땐 java.util.concurrent package 에서 제공하는 Executor, ThreadPoolExecutorFutureTask 같은 다양한 API 를 사용하는걸 더 추천합니다.


asynchronous task(비동기 작업) 는 백그라운드 스레드에서 실행되고, 그 결과를 UI 스레드에 퍼블리시 되는 것을 산정하는 것으로 정의됩니다. 이 비동기 작업은 , called Params(호출 파라미터), progress and result(진행과 결과), 3가지 generic types(제너릭 타입), onPreExecute, doInBackground, onProgressUpdate, onPostExecute 를 호출하는 4개의 스텝으로 정의됩니다.


Developer Guides

태스크와 스레드를 사용하는 방법에 대한 자세한 정보는, Progresses and Threads 개발자 가이드를 참조하세요.




Usage



AsyncTask 를 사용하려면 subcalss(서브클래스) 를 구현해야합니다. 이 서브클래스는 적어도 하나의 메소드, doInBackground(Params...) 는 오버라이드 해야 하구요, 그리고 가끔은 두번째 메소드로 onPostExecute(Result) 를 오버라이드 할거에요.


아래는 서브클래스의 예제 코드입니다.


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);



AsyncTask's generic types



이 세가지 타입은 비동기 작업(asynchronous task)에 의해 사용됩니다.


  1. Params, 실행시 태스크에 보내지는 파라미터의 타입입니다.
  2. Progress, 백그라운드 계산 동안 퍼블리시 되는 진행 단위(progress units)의 타입입니다.
  3. Result, 백그라운드 계산 결과의 타입입니다.


이 모든 타입들이 항상 비동기 작업에서 사용되지는 않습니다. 사용하지 않는 유형을 표시하려면 간단하게 Void 타입을 사용하면 됩니다.




The 4 Steps



비동기 작업이 실행될때, 태스크는 네가지 단계를 진행합니다.


  1. onPreExecute(), 작업 실행 전, UI 스레드에서 호출됩니다. 이 단계는 일반적으로 유저 인터페이스에 프로그레스바 를 보여주는 것 같은 태스크 셋업에 사용됩니다.
  2. doInBackground(Params... ), onPreExecute() 실행이 끝나면 백그라운드 스레드에서 즉시 호출됩니다. 이 단계는 백그라운드 계산을 수행하는데 사용되고, 시간이 오래걸릴 수 있습니다. 비동기 작업의 파라미터(위의 Params)는 이 단계에 전달됩니다. 계산 결과는 여기서 반환해야 하며 마지막 단계로 전달됩니다. 하나 또는 더 많은 단위의 프로그레스를 퍼블리시 하기 위해 publishProgress(Progress...) 를 사용할 수 있습니다. 이 값들은 onProgressUpdate(Progress...) 단계에서 UI 스레드에 퍼블리시 됩니다.
  3. onProgressUpdate(Progress... ), publishProgress(Progress...) 가 호출되고 난 후, UI 스레드에서 호출됩니다. 실행 타이밍은 정의되지 않습니다. 이 메소드는 백그라운드 계산이 여전히 실행되는 동안에는 유저인터페이스에 진행 형태를 보여주는데 사용됩니다. 예를 들면,  프로그레스바 애니메이션이나, 텍스트 필드에 로그를 보여주는데 사용될 수 있습니다.
  4. onPostExecute(Result), 백그라운드 계산이 완료되면 UI 스레드에서 호출됩니다. 백그라운드 계산 결과는 이 단계에 파라미터로 전달됩니다.




Cancelling a task



태스크는 cancel(boolean) 을 호출해서 언제든지 취소될 수 있습니다. 이 메소드를 호출하면 isCancelled() 호출되면 true 를 리턴하는 서브 시퀀스를 발생시킵니다. 이 메소드 호출된 후에는, doInBackground(Object[]) 반환 후에 onPostExecute(Object) 대신에 onCancelled(Object) 가 호출됩니다. 작업이 취소되었는지 가능한 빨리 확인하려면, doInBackground(Object[]) 에서 isCancelled() 반환값을 주기적으로 확인해줘야 합니다. 가능한 경우에 말이죠.(예를들어 loop 내부에요.)




Threading rules



이 클래스가 제대로 동작하려면 몇가지 스레딩 규칙을 따라야 합니다.


  • AsynTask 클래스는 UI 스레드에서 로드 되어야만 합니다. 이건 JELLY_BEAN 에선 자동으로 이루어집니다.
  • 태스크 인스턴스는 UI 스레드에서 생성되어야만 합니다.
  • execute(Params...) 는 UI 스레드에서 호출해야합니다.
  • 수동으로(프로그래머가 직접) onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) 호출하지 마십시오.
  • 태스크는 오직 한번만 실행될 수 있습니다.(두번째 실행하려고 시도하면 예외가 발생합니다.)




Memory observability



AsyncTask 는 명시적인 동기화 없이, 다음과 같은 안전한 방법으로 모든 콜백 호출은 동기화 된다는 것을 보장합니다.


  • 생성자, 또는 onPreExecute() 에서 멤버 필드를 설정하고, doInBackground(Params...) 에서 참조한다.
  • doInBackground(Params...) 에서 멤버 필드를 설정하고, onProgressUpdate(Progress...) 와 onPostExecute(Result) 에서 참조한다.




Order of execution



처음 소개되었을 땐, AsyncTask 는 하나의 백그라운드 스레드에서 순차적으로 실행되었습니다. 도넛을 시작으로, 여러 태스크를 병렬로 작업할 수 있도록 스레드풀로 변경되었습니다. 허니콤을 시작으로, 병렬 실행에 의해 발생하는 일반적인 애플리케이션 오류를 피하기 위해 태스크는 싱글 스레드에서 실행됩니다.


정말로 병렬 실행을 원한다면, THREAD_POOL_EXECUTORexecuteOnExecutor(java.util.concurrent.Executor, Object[])) 를 호출할 수 있습니다.




Croute's Summary



1. AsyncTask 는 백그라운드에서 비동기 작업을 실행하기 위한 클래스이다.

2. AsyncTask 를 사용하기 위해서는 Subclass 를 구현해야한다.

3. AsyncTask 는 몇초 정도 걸리는 짧은 작업에 사용할 것을 권장한다.

4. AsyncTask 는 Single thread 에서 동작한다. (버전별로 다르긴 하지만, 3.0 이후 굳어짐)
    멀티스레딩을 원하면, 스레드풀 및 executeOnExcutor 를 사용해야한다.

5. UI 스레드에서 생성, 로드, 실행해야 한다.

6. cancel 메소드를 사용해 언제든지 취소할 수 있다.


간단하게 정리해보면, 이런 내용이겠네요.

UI 스레드에 바짝 붙어서만 동작될 수 있고, 싱글 스레드이고, 짧은 작업을 비동기로 백그라운드에서 실행하기위한 클래스이며 일반적인 비동기에 사용하는 Thread 하곤 다르게 cancel 을 사용해 취소하기 쉽다.




Summary


Nested Classes
enumAsyncTask.StatusIndicates the current status of the task. 

Fields
public static final ExecutorSERIAL_EXECUTORAn Executor that executes tasks one at a time in serial order.
public static final ExecutorTHREAD_POOL_EXECUTORAn Executor that can be used to execute tasks in parallel.
Public Constructors
AsyncTask()
Creates a new asynchronous task.
Public Methods
final booleancancel(boolean mayInterruptIfRunning)

Attempts to cancel execution of this task.

static voidexecute(Runnable runnable)
Convenience version of execute(Object) for use with a simple Runnable object.
final AsyncTask<Params, Progress, Result>execute(Params... params)
Executes the task with the specified parameters.
final AsyncTask<Params, Progress, Result>executeOnExecutor(Executor exec, Params... params)
Executes the task with the specified parameters.
final Resultget(long timeout, TimeUnit unit)
Waits if necessary for at most the given time for the computation to complete, and then retrieves its result.
final Resultget()
Waits if necessary for the computation to complete, and then retrieves its result.
final AsyncTask.StatusgetStatus()
Returns the current status of this task.
final booleanisCancelled()
Returns true if this task was cancelled before it completed normally.
Protected Methods
abstract ResultdoInBackground(Params... params)
Override this method to perform a computation on a background thread.
voidonCancelled(Result result)

Runs on the UI thread after cancel(boolean) is invoked anddoInBackground(Object[]) has finished.

voidonCancelled()

Applications should preferably override onCancelled(Object).

voidonPostExecute(Result result)

Runs on the UI thread after doInBackground(Params...).

voidonPreExecute()
Runs on the UI thread before doInBackground(Params...).
voidonProgressUpdate(Progress... values)
Runs on the UI thread after publishProgress(Progress...) is invoked.
final voidpublishProgress(Progress... values)
This method can be invoked from doInBackground(Params...)to publish updates on the UI thread while the background computation is still running.



'Android > Handler & AsyncTask' 카테고리의 다른 글

Handler - android.os.Handler  (0) 2013.01.17