728x90

AsyncTask

- 클래스 하나에 Thread 와 Handler 의 기능이 콜백 메서드로 모두 존재


AsyncTask 클래스는 Thread 나 Looper 등의 작동 원리를 몰라도 하나의 클래스에서 UI 처리 및 Background 작업들을 쉽게 할 수 있도록 안드로이드에서 제공하는 클래스다.

이 클래스를 활용하면 작업을 백그라운드에서 수행할 수 있으며, 핸들러나 Thread 를 건들 필요 없이, 백그라운드에서 수행한 결과를 UI Thread(Main Thread) 로 보낼 수 있게 된다.

이렇게 백그라운드에서 수행되는 비 동기적인 작업은 세 가지 generic 타입 - Params, Progress, Result -

과 네 가지 스텝 - onPreExecute, doInBackground, onProgressUpdate, onPostExecute 으로 구성된다.


AsyncTask<Params, Progress, Result> 와 같이 제네릭 인수로  3가지 타입을 전달받는데 사용하지 않는 타입은 Void 라고 적으면 된다.

- Params : 실행할 전달한 인수의 타입. 즉 execute(..) 메소드의 파라미터를 통해 넘겨주는 값의 타입을 지정

- Progress : onProgressUpdate()가 호출될 때 넘겨받을 인자를 뜻한다.

- Result : 작업의 결과로 리턴될 타입 (onPostExecute()가 호출될 때넘겨받을 인자)



@Override

protected void onPreExecuted() { ... }

 //  Background 작업 시작전에 호출되며 UI 쓰레드에서 실행된다.

      계산을 위한 초기화나 프로그래스 대화상자 등의 작업을 수행한다

@Override

protected String doInBackground(Params... params)  { ... }  // 필수 메소드

 // background 작업을 수행하며 분리된 작업 쓰레드에서 실행된다.

     execute 메소드로 전달한 작업거리가 params 인수로 전달되는데 여러 개의 인수를 전달 할 수 있으므로 배열 타입으로 되어있다. 하나의 인수만 필요하다면 params[0] 만을 사용하면 된다.  (가변인자는 JDK 5.0 부터 지원)

작업중에 publishProgress 메소드르 호출하여 작업 경과를 UI Thread로 보고 할 수 있다.

그리고 최종 작업된 결과를 Result 타입으로 반환하며, 결과 값은 onPostExcute() 로 전달된다.

이 쓰레드 안에서 UI를 조작하면 에러가 발생한다.


@Override

 protected void onPostExecute(String result) { .... }

//이 메소드는 doInBackground() 메소드가 완료된 후에 호출된다.
// doInBackground() 메소드 작업의 결과가 return 되어 이 메소드에 전달된다.

// 여기에서 UI Thread 로 보낼 UI 조작을 할 수 있다.


AsyncTask를 사용해서 스케줄링 할 수 있는 작업 수의 제한이 있고, 몇 초 정도의 짧은 작업에서만 이상적으로 동작한다는 한계가 있다.
또한, 안드로이드의 버전별로 병렬 처리 동작이 다르므로 허니콤 이후 버전에서 멀티 스레드로 병렬적인 동작을 원한다면 AsyncTask를 실행할 때 AsyncTask.THREAD_POOL_EXECUTOR 스케줄러를 지정해야 한다.




(Example)


private class DownloadFiles 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));
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {

         // Background 작업 진행상태 표시할 때 호출
         setProgressPercent(progress[0]);
     }

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



사용법

DownloadFiles asyncTask = new DownloadFiles();
asyncTask.execute();

한번에 쓰면
new DownloadFiles().execute();


하지만 cancel 처리도 발생하는 걸 고려한다면
new DownloadFiles().execute(); 로 사용하면 안된다.


DownloadFiles asyncTask = new DownloadFiles();

asyncTask.execute();

asyncTask.cancel(true);

로 해야 된다.


Android Studio 실제 코드 구현시에는 try catch 를 해주어야 에러메시지가 나오지 않는다.

try catch는 Alt + Enter 눌러서 해당 항목 선택해주면 자동으로 코드가 추가된다.



블로그 이미지

Link2Me

,