AsyncTask 클래스

HEETAE HEO·2022년 6월 29일
0
post-thumbnail

AsyncTask

AsyncTask는 그 이름에서도 알 수 있듯이, 비동기(Asynchronous)적으로 실행될 필요가 있는 작업(Task)을 위해 사용하는 클래스 입니다. 특히 Thread, Handler, Message, Runnable 등을 직접 다루지 않아도 메인 스레드와 별개로 비동기 실행이 필요한 작업에 사용할 수 있습니다.

AsyncTask 주요 재정의 함수

Android의 AsyncTask 생명주기 관리는 다섯 가지의 생명주기 함수들을 재정의함으로써 관리할 수 있습니다.

  • doInBackground() 함수를 제외한 나머지 4개의 함수는 전부 MainThread에서 실행되는 함수들입니다. 그래서 doInBackground() 함수는 메인스레드와는 별개로 오래 걸리는 작업을 처리합니다.

  • AsyncTask를 실행하면 가장 먼저 onPreExecute() 함수가 호출되며 doInBackground()함수가 호출되기 직전에 호출됩니다. 일반적으로 해당 함수에서는 사용자 UI에 ProgressBar를 표시하여 본격적인 작업 스레드에 들어가기 전에 작업 진행 줄을 펴시하는 구현이 들어갑니다.

  • onProgressUpdate() 함수는 doInBackground()함수에서 publishProgress() 함수를 호출하면 호출되는 함수로 작업 스레드를 실행하는 도중에 UI처리를 담당합니다. 일반적으로 작업 진행 정도를 표시하는 용도로 사용됩니다.

  • doInBackground() 실행 도중 작업이 중단되는 경우에 onCancelled()함수가 실행됩니다. 반대로 정상적으로 처리가 완료되는 경우에는 onPostExecute() 함수가 호출됩니다.

구현

코드 : https://lab.cliel.com/entry/Kotlin-AsyncTask

class MainActivity : AppCompatActivity() {
    private lateinit var mytv: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mytv = findViewById(R.id.textView)

        asyncTask.execute()
    }

    val asyncTask = object : AsyncTask<Void, Int, String>() {
        override fun doInBackground(vararg params: Void?): String {
            for (i in 0..10) {
                publishProgress(i)
                Thread.sleep(1000)
            }

            return "10까지 완료"
        }

        override fun onProgressUpdate(vararg values: Int?) {
            super.onProgressUpdate(*values)

            mytv.text = "${values[0]!!}"
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)

            mytv.text = result
        }
    }
}

3개의 함수에는 전달되는 파라미터가 각각 있습니다.

  • params : AsyncTask 실행에 필요한 파라미터
  • Progress : 현재 작업 진행 정보를 나타내는 상태 값
  • Result : 작업의 실행이 완료된 후의 최종 결과

이러한 역할을 가지고 있습니다.

doInBackground()

해당 메서드에서는 실제 처리되어야 하는 코드가 들어가며 해당 코드는 백그라운드 스레드에서 동작을 수행합니다. 위에 액션에서는 for문을 통해 0 부터 10까지 돌면 publishProgress()함수를 수행합니다.

onPorgressUpdate()

publishProgress()를 수행할 때마다 호출되는 메서드로 호출될때 들어있는 매개변수의 값을 받아서 mytv.text로 넣는 역할을 수행합니다. 각 메서드의 매개변수는 varag로 되어있는데 탑에 해당하는 변수의 값을 구분해서 전달할 수 있음을 의미합니다.

onPostExecute()

doInBackground() 메서드가 return을 통해 값을 반환하면 호출되는 메서드로 Result에서 지정한 String 형식과 반환형식이 동일하며 return 값을 받아서 동작을 수행합니다. 위의 코드에서는 onPorgressUpdate()와 마찬가지로 text를 변경합니다.

이제 Deprecated된 AsyncTask

Deprecated된 이유 중 사용상으로의 단점은 오직 한 번만 실행되어 재사용이 불가능하다는 것과 종료를 직접해주지 않으면 종료가 되지 않아 메모리 누수가 발생한다는 점입니다. 그리고 UI스레드에서 호출해야 한다라는 문제들이 존재합니다.

시스템 상으로는

  1. Memory leak
  • 화면이 회전할 때 액티비티는 종료되었다가 재생성되는데 AsyncTask가 계속 중첩되어 실행될 수가 있습니다. 게다가 AsyncTask가 실행되고 있던 도중에 화면 회전이 일어나게 되면 기존 Activity조차 메모리에서 해제되지 않는다는 단점이 존재합니다.
  1. 순차적으로 실행되기 때문에 속도의 저하가 될 수 있습니다.
  2. Fragment에서 AsyncTask를 실행할 경우
    -> Fragment에서 AsyncTask를 실행하고 뒤로가기 키를 통해 Actvity를 종료하면 Fragment가 Activity와 분리되면서 getContext(), getActivity() 등이 null을 반환하게 되어 onPostExecute()에서 NullPointerException이 발생합니다.
  3. 취소 메서드만 있고, onError()와 같은 예외처리 메소드는 없습니다.
  4. AsyncTask 병렬 실행 시 doInBackground()의 실행순서가 보장되지 않습니다.

그렇기에 AsyncTask는 2019년에 Deprecated 되었습니다

대체하는 기술들

  • RxJava
  • Coroutine
profile
Android 개발 잘하고 싶어요!!!

0개의 댓글