ANDROID/Android 앱 프로그래밍
[Android] AsyncTask 사용하기
주 녕
2021. 6. 23. 14:34
반응형
모든 내용은 Do it! 안드로이드 앱 프로그래밍을 바탕으로 정리한 것입니다.
기존에 사용했던 핸들러는 코드가 복잡함 && 코드가 순서없이 이곳저곳에서 실행되는 느낌
→ 핸들러(Handler)를 사용하지 않고 좀 더 간단하게 하는 방법 : AsyncTask
AsyncTask
AsyncTask 클래스를 상속받아 새로운 클래스를 만들면 그 안에 스레드를 위한 코드와 UI 접근 코드를 한번에 넣을 수 있음
→ 스레드로 처리해야 하는 코드를 하나의 AsyncTask 클래스로 정의할 수 있다는 장점!
AsyncTask 클래스를 상속하여 새로운 클래스를 정의하면 그 내부에서 필요한 경우마다 콜백 메서드들이 자동으로 호출됨.
아래의 설명과 같이 AsyncTask 클래스를 사용하면 UI 객체에 접근할 수 있기 때문에 하나의 클래스 안에 스레드에서 동작해야 하는 작업과 그 작업의 결과를 UI에 반영하는 코드를 같이 구현할 수 있음.
→ 스레드로 수행해야 할 어떤 기능을 하나의 클래스 만으로 만들 수 있음
[ 새로운 스레드에서 동작하는 메서드 ]
- doInBackground() 메서드
- 새로 만들어진 스레드에서 백그라운드 작업을 수행함
- execute() 메서드를 호출할 때 사용된 파라미터를 배열로 전달받음
[ 메인 스레드에서 동작하는 메서드 ]
- onPreExecute() 메서드
- 백그라운드 작업을 수행하기 전에 호출됨
- 메인 스레드에서 초기화 작업에 사용됨
- onProgressUpdate() 메서드
- 백그라운드 작업의 진행 상태를 표시하기 위해 호출됨
- 작업 수행 중간 중간에 UI 객체에 접근하는 경우에 사용됨
- 이 메서드가 호출되려면 백그라운드 작업 중간에 publishProgress() 메서드를 호출해야 함
- onPostExecute() 메서드
- 백그라운드 작업이 끝난 후에 호출됨
- 메인 스레드에서 실행되며 메모리 리소스를 해제하는 등의 작업에 사용됨
- 백그라운드 작업의 결과는 Result 타입의 파라미터로 전달됨
[ 그 외의 메서드 ]
- execute() 메서드
- 정의된 백그라운드 작업을 수행하고 필요 시 결과를 메인 스레드에서 실행하는 메서드
- cancel() 메서드
- 작업을 취소하는 메서드
- 이 메서드로 작업을 취소했을 때, onCancelled() 메서드가 호출됨
- getStatus() 메서드
- 작업의 진행 상황을 확인하고 싶을 때 사용하는 메서드
- PENDING(시작 전), RUNNING(실행 중), FINISHED(종료) 상태로 구분됨
[예제]
public class AsyncActivity extends AppCompatActivity {
BackgroundTask task;
int value;
ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async);
progressBar = findViewById(R.id.async_progress);
Button executeButton = findViewById(R.id.async_execute_btn);
executeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 태스크 객체 만들어 실행시키기
task = new BackgroundTask();
task.execute();
}
});
Button stopButton = findViewById(R.id.async_stop_btn);
stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
task.cancel(true);
}
});
}
class BackgroundTask extends AsyncTask<Integer, Integer, Integer> {
// <> 안의 자료형은 재정의할 새로운 클래스의 메서드가 어떤 자료형의 파라미터를 갖는지 알려줌
@Override
protected void onPreExecute() {
super.onPreExecute();
value = 0;
progressBar.setProgress(value);
}
@Override
protected Integer doInBackground(Integer... integers) {
while (isCancelled() == false) {
value++;
if (value >= 100) {
break;
} else {
// 중간 중간 진행상태를 업데이트하기 위해 호출
publishProgress(value);
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {}
}
return value;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setProgress(values[0].intValue());
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
progressBar.setProgress(0);
}
@Override
protected void onCancelled() {
super.onCancelled();
progressBar.setProgress(0);
}
}
}
- AsyncTask 클래스를 상속하는 코드를 보면 < > 사이에 자료형들이 정의되어 있음
- 이 클래스를 상속하면서 재정의할 새로운 클래스의 메서드가 어떤 자료형의 파라미터를 가질 것인지를 알려주는 역할
- < > 안에 명시한 자료형은 순서에 따라 doInBackgorund()의 파라미터, onProgressUpdate()의 파라미터, onPostExecute()의 파라미터를 결정함
- onPreExecute() 메서드는 초기화 단계에서 사용되므로 값을 저장하기 위해 value 변수의 값과 프로그래스바의 값을 초기화함
- doInBackground() 메서드는 주된 작업을 실행하는데 사용됨
- 중간 중간 진행상태를 UI에 업데이트하도록 만들기 위해 publishProgress() 메서드를 호출함
- onProgressUpdate() 메서드는 doInBackground()에서 publishProgress() 메서드가 호출될 때마다 자동으로 호출됨
반응형