본문 바로가기
Android

[깡샘의 안드로이드 프로그래밍] 정리 18 - AsyncTask

by 들풀민들레 2018. 1. 5.

 

본 글은 [깡샘의 안드로이드 프로그래밍 - 루비페이퍼] 의 내용을 발췌한 것입니다.
좀더 자세한 내용은 책을 통해 확인해 주세요.

 

 

 

 

 

 

16장. 스레드와 핸들러

 

16.2.1. AsyncTask

 

액티비티 ANR 문제를 해결하기 위해 스레드를 만들고 스레드에 의한 뷰 작업을 위해 핸들러를 이용하는 구조를 살펴보았는데요. 이 스레드-핸들러 구조의 프로그램을 작성할 수 있는 또 다른 방법이 AsyncTask 클래스입니다. 

앞에서 살펴보았던 스레드-핸들러 구조로 프로그램을 작성해도 되고, 이번 절에서 소개하는 AsyncTask 클래스를 이용해서 작성해도 됩니다. 목적은 같으며 두 방법 모두 많이 이용됩니다. AsyncTask는 전혀 새로운 구조의 프로그램이 아니며 앞에서 살펴보았던 스레드- 핸들러의 추상화 개념 정도로 이해하면 됩니다.

 

AsyncTask을 이용하려면 AyncTask를 상속받는 클래스를 작성합니다. 다음은 AsyncTask 클래스에 정의된 함수들입니다.

 

  • doInBackground(Params... params): 스레드에 의해 처리될 내용을 담기 위한 함수
  • onPreExecute(): AsyncTask의 작업을 시작하기 전에 호출. AsyncTask에서 가장 먼저 한 번 호출
  • onPostExecute(Result result): AsyncTask의 모든 작업이 완료된 후 가장 마지막에 한 번 호출. doInBackground() 함 수의 최종 값을 받기 위해 사용
  • onProgressUpdate(Progress... values): doInBackground() 함수에 의해 처리되는 중간중간 값을 받아 처리하기 위해 호출. doInBackground( ) 함수에서 publishProgress( ) 함수로 넘긴 값이 전달

 

AsyncTaks 클래스는 추상 클래스이며 위의 함수 중 추상 함수인 doInBackground ( )는 꼭 재정의해서 작성해야 합니다. 그리고 나머지 함수들은 필요할 때 재정의해서 작성합니다.

 

class MyAsyncTask extends AsyncTask<Void, Integer, String> {

@Override

protected String doInBackground(Void... params) {

//...

}

@Override

protected void onProgressUpdate(Integer... values) {

}

@Override

protected void onPostExecute(String values) {

}

}

 

 

AsyncTask 클래스를 상속받을 때 제네릭을 이용하여 타입을 정확하게 지정하고 사용해야 합니다.

위의 코드에서 class MyAsyncTask extends AsyncTask<Void, Integer, String> 부분을 보면 3가지 타입을 지정하여 사용하고 있습니다.

 

  • 첫 번째 타입: 백그라운드 작업을 위한 doInBackground( ) 함수의 매개변수 타입과 동일. AsyncTask에 의해 백그라운드 작업을 의뢰할 때 넘길 데이터의 타입. 없으면 Void로 지정
  • 두 번째 타입: doInBackground( ) 함수 수행에 의해 발생한 데이터를 publishProgress( ) 함수를 이용해 전달하는데 이때 전달할 데이터 타입. 데이터를 전달받을 onProgressUpdate( ) 함수의 매개변수의 타입과 동일하게 지정
  • 세 번째 타입: onPostExecute( ) 함수의 매개변수 타입과 동일하게 지정 doInBackground( ) 함수의 반환형이며 반환된 데이터가 onPostExecute( ) 함수의 매개변수로 전달됨

 

 

doInBackground( ) 함수는 장시간 수행되는 업무를 구현하는 곳입니다. 스레드 프로그램을 직접 작성한다면 스레드의 run ( ) 함수에 구현될 내용을 doInBackground( ) 함수에 작성하면 됩니다.

결국, doInBackground ( ) 함수는 스레드의 run ( ) 함수이므로 이곳에서 뷰 객체에 접근할 수 없습니다. 이곳에서는 장시간 수행해야 하는 업무만 구현하고 업무 수행 결과에 의한 뷰 작업은 onPostExecute( )나 onProgressUpdate( ) 함수에 작성합니다.

 

onPostExecute ( ) 함수는 doInBackground ( ) 함수에서 작업이 완료되면 자동으로 호출되며 doInBackground ( ) 함수에서 반환한 값이 onPostExecute ( ) 함수의 매개변수로 전달됩니다.

그런데 때에 따라서 doInBackground( ) 함수 수행 도중에 뷰에 접근이 필요할 수 있습니다. 이때 doInBackground( ) 함수에서 publishProgress ( ) 함수를 호출하여 자동으로 onProgressUpdate( ) 함수가 호출되게 할 수 있습니다.

 

이렇게 완성된 AsyncTask 클래스를 수행하려면 클래스를 생성한 다음 execute( ) 함수를 호출해 주면 됩니다.

 

MyAsyncTask task=new MyAsyncTask();

task.execute();