[Android] AsyncTask - UI 스레드에서는 시간이 오래 걸리는 일을 하면 안 된다
안드로이드는 메인 스레드에서 UI와 관련된 일을 처리한다. 그래서 메인 스레드를 UI 스레드라고 부르기도 한다. 그런데 UI 스레드에서 오랫동안 CPU를 점유하는 일을 하게 되면, "
이런 일을 방지하기 위해서는 새로운 스레드를 생성하여 다른 스레드에 시켜야 한다. 하지만 로우레벨의 스레드를 바로 사용하면 동기화하는 과정에서 쉽게 실수할 수 있으므로 실수 없이 쉽게 스레드를 사용할 수 있게 하려고 안드로이드는 AsyncTask
라는 클래스를 지원한다.
AsyncTask
는 UI 스레드에서 잠시 동안 백그라운드로 일을 호출하고 싶을 때 사용된다. 잠시 동안이라는 것을 문서상으로는
대표적인 문제는, AsyncTask
가 Activity
에 종속되지 않기 때문에, AsyncTask
를 호출했던 Activity
가 먼저 죽었을 경우 처리가 복잡해진다.
또 다른 문제는 백그라운드 스레드를 점유해버린다는 것이다. AsyncTask
는 AsyncThread
가 새로 만들어질 때마다 스레드를 생성하지 않는다. 고정된 크기의 스레드 풀이 있고 이 스레드 풀을 모든 AsyncTask
가 공유한다. API 버전에 따라서 1개의 태스크만 실행될 수도 있고, 여러 개의 태스크가 병렬적으로 동시에 수행될 수도 있는데, 최신 버전은 1개만 실행되며 모든 태스크는 순차적으로 실행하게 되어 있다. 따라서 어떤 태스크가 데 시간이 오래 걸린다면 다른 태스크가 실행되지 못한다.
AsyncTask
를 사용하는 대략적인 과정은 다음과 같다. AsyncTask
를 상속받는 클래스를 만들어서 필요한 함수를 오버라이드한다. 그 뒤 UI 스레드에서 AsyncTask
를 상속한 클래스의 객체를 생성하여 execute
메소드를 실행시킨다. AsyncTask
는 3개의 타입 파라미터를 받는다. 각각은 순서대로 Params
, Progress
, Result
라고 부른다. Params
는 태스크를 실행시킬 때 넘기는 파라미터의 타입이고, Progress
는 UI 스레드에 태스크의 진행 상황을 넘기기 위해서 사용되는 파라미터의 타입이고, Result
는 태스크의 결과를 UI 스레드에 넘길 때 사용되는 타입이다.
AsyncTask
를 상속받는 클래스는 반드시 doInBackground
함수를 구현해야 한다. 이 함수는 태스크를 백그라운드에서 실행시킬 일을 의미한다. 이 함수는 자동으로 백그라운드 스레드에서 실행되며, 수동으로 실행시켜서는 안 된다. 또한 이는 백그라운드 스레드에서 실행되기 때문에 UI를 수정하면 안 된다. 중간에 UI를 수정하고 싶으면 publishProgress
함수를 호출하여 UI 스레드에서 콜백이 실행되도록 해야 한다.
그 외에 필요에 따라서 onPreExecute
, onPostExecute
, onProgressUpdate
, onCancelled
함수를 구현할 수 있다. 각각 태스크가 수행되기 전, 수행된 후, publishProgress
함수가 불렸을 때, 태스크가 취소됐을 때 UI 스레드에서 호출된다. 위의 상황에서 UI를 변경시키고자 할때는 위의 함수들을 구현해서 사용해야 한다.
1) https://developer.android.com/intl/ko/reference/android/os/AsyncTask.html
댓글
댓글 쓰기