android.os.AsyncTask
Class Overview
AsyncTask 는 UI 스레드를 적절하고 쉽게 사용할 수 있게 합니다. 이 클래스는 스레드와 핸들러를 정교하게 다루는 것 없이, 백그라운드 작업을 수행하고, UI 스레드에 결과를 퍼블리쉬 할 수 있게 합니다.
AsyncTask 는 스레드와 핸들러에 대한 헬퍼 클래스가 될 수 있도록 설계되어있으며, 제너릭 스레딩 프레임워크를 구성하지 않습니다. AsyncTask 는 (최대 몇초 밖에 안걸리는) 짧은 작업에 사용되어야합니다.
오랫동안 스레드를 유지해야 하는 경우라면, 그땐 java.util.concurrent package 에서 제공하는 Executor, ThreadPoolExecutor 와 FutureTask 같은 다양한 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)에 의해 사용됩니다.
- Params, 실행시 태스크에 보내지는 파라미터의 타입입니다.
- Progress, 백그라운드 계산 동안 퍼블리시 되는 진행 단위(progress units)의 타입입니다.
- Result, 백그라운드 계산 결과의 타입입니다.
이 모든 타입들이 항상 비동기 작업에서 사용되지는 않습니다. 사용하지 않는 유형을 표시하려면 간단하게 Void 타입을 사용하면 됩니다.
The 4 Steps
비동기 작업이 실행될때, 태스크는 네가지 단계를 진행합니다.
- onPreExecute(), 작업 실행 전, UI 스레드에서 호출됩니다. 이 단계는 일반적으로 유저 인터페이스에 프로그레스바 를 보여주는 것 같은 태스크 셋업에 사용됩니다.
- doInBackground(Params... ), onPreExecute() 실행이 끝나면 백그라운드 스레드에서 즉시 호출됩니다. 이 단계는 백그라운드 계산을 수행하는데 사용되고, 시간이 오래걸릴 수 있습니다. 비동기 작업의 파라미터(위의 Params)는 이 단계에 전달됩니다. 계산 결과는 여기서 반환해야 하며 마지막 단계로 전달됩니다. 하나 또는 더 많은 단위의 프로그레스를 퍼블리시 하기 위해 publishProgress(Progress...) 를 사용할 수 있습니다. 이 값들은 onProgressUpdate(Progress...) 단계에서 UI 스레드에 퍼블리시 됩니다.
- onProgressUpdate(Progress... ), publishProgress(Progress...) 가 호출되고 난 후, UI 스레드에서 호출됩니다. 실행 타이밍은 정의되지 않습니다. 이 메소드는 백그라운드 계산이 여전히 실행되는 동안에는 유저인터페이스에 진행 형태를 보여주는데 사용됩니다. 예를 들면, 프로그레스바 애니메이션이나, 텍스트 필드에 로그를 보여주는데 사용될 수 있습니다.
- 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_EXECUTOR 와 executeOnExecutor(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 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
AsyncTask.Status | Indicates the current status of the task. |
Fields | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
SERIAL_EXECUTOR | An Executor that executes tasks one at a time in serial order. | ||||||||||
THREAD_POOL_EXECUTOR | An Executor that can be used to execute tasks in parallel. |
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Creates a new asynchronous task. |
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Attempts to cancel execution of this task. | |||||||||||
Convenience version of execute(Object) for use with a simple Runnable object. | |||||||||||
Executes the task with the specified parameters. | |||||||||||
Executes the task with the specified parameters. | |||||||||||
Waits if necessary for at most the given time for the computation to complete, and then retrieves its result. | |||||||||||
Waits if necessary for the computation to complete, and then retrieves its result. | |||||||||||
Returns the current status of this task. | |||||||||||
Returns true if this task was cancelled before it completed normally. |
Protected Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
Override this method to perform a computation on a background thread. | |||||||||||
Runs on the UI thread after | |||||||||||
Applications should preferably override | |||||||||||
Runs on the UI thread after | |||||||||||
Runs on the UI thread before doInBackground(Params...) . | |||||||||||
Runs on the UI thread after publishProgress(Progress...) is invoked. | |||||||||||
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 |
---|