본문 바로가기

Android/Basic

[Android] AsyncTask

AsyncTask 는 API 30 부터 Deprecate 되었습니다. 공식문서 참고



스레드를 사용하여 UI를 변경하고 싶다면, 메인스레드에 붙어있는 핸들러에게 요청해야한다는 것을 이미 알고있다.

Runnable 객체, post 메소드를 이용해서 좀 더 간단하게 구현하는 방법도 있다.

하지만, 여전히 복잡하고 코드가 길어 해석하는데에 어려움이 있다.


핸들러를 사용하는 코드가 복잡하게 느껴지는 이유는, 스레드 안에서 실행되어야할 코드와 UI 접근을 위한 코드가 각각 다른 위치에서 구현해야하기 때문이다.


이러한 혼란스러움을 해결하기 위한 방법은 바로 AsyncTask!


AsyncTask는 하나의 클래스 안에 스레드로 동작하는 부분과 화면을 갱신하는 부분을 함께 구현해놓을 수 있다.

이 때문에 스레드를 사용하는 하나의 작업단위가 하나의 클래스로 만들어질 수 있게 된다! (가독성이 훨씬 더 좋아진다.)


아래는 AsyncTask 클래스를 상속받아 구현한 것이다.

여기서 doInBackground는 필수로 구현되어야 할 메소드이다.

상속받을때 <> 안에 들어있는 파라미터는 각각 메소드의 파라미터가 된다.

class ProgressTask extends AsyncTask<String, Integer, Integer> {
int value = 0;
boolean running = true;

@Override
protected Integer doInBackground(String... strings) { // ... : 가변 파라미터
// AsyncTask를 실행하면 이 콜백 메소드가 자동으로 호출됨
// 스레드 안에서 처리할 코드를 구현하면 됨
while (running) {
if (value > 100) break;
value += 1;

try {
Thread.sleep(200);
} catch (Exception e) {
}

publishProgress(value);
}

return value;
}

@Override
protected void onProgressUpdate(Integer... values) {
// 중간중간에 UI 업데이트.
// doInBackground 메소드 안에서 publishProgress를 호출하면 이 메소드가 호출 됨
super.onProgressUpdate(values);

progressBar.setProgress(values[0].intValue());
}

@Override
protected void onPostExecute(Integer integer) {
// 모든 작업이 끝난 후 호출되는 메소드(스레드 종료, 화면 갱신 완료)
super.onPostExecute(integer);

Toast.makeText(MainActivity.this, "완료됨.", Toast.LENGTH_SHORT).show();
}
}


AsyncTask 객체를 생성하여 실행하면 끝!

ProgressTask task = new ProgressTask();
task.execute("시작"); // 이 문자열은 doInBackground에 전달