1. 개요
스레드를 사용하면서 UI 객체에 접근하려면 핸들러를 통하면 된다. 하지만 Message 객체를 사용할 경우 코드가 길어진다는 문제가 생긴다.
AsyncTask는 하나의 클래스 안에 스레드로 동작하는 부분과 UI 객체에 접근하는 부분을 함께 넣을 수 있도록 합니다.
이 때문에 스레드를 사용하는 하나의 작업 단위가 AsyncTask라는 하나의 클래스로 만들어질 수 있다.
1. AsyncTask
- AsyncTask는 비 동기 처리를 위해 제공되는 클래스 이다.
- 개발자가 발생 시키는 쓰레드와 핸들러의 조합으로 쓰레드 운영 중 화면 처리가 가능했던 구조를 클래스로 제공하는 것이다.
- AsyncTask를 사용하면 개발자가 발생시키는 일반쓰레드와 화면 처리를 위해 MainThread를 이용하는것을 조합하여 작업이 가능하다.
2. 오버라이드 주요 메서드
1. onPreExeCute()
- doInBackground 메서드가 호출되기 전에 호출되는 메서드.
- Main Thread가 처리한다.
- 5초 이상의 작업을 하면 안되고, 화면 처리가 가능하다.
2. doInBackground()
- 일반 Thread에서 처리한다.
- 네트워크 작업 or 5초 이상 걸리는 작업을 이 메서드에서 처리한다.
3. onProgressUpdate()
- doInBackground 메서드에서 publishProgress 메서드를 호출하면 Main Thread가 처리하는 메서드.
- doInBackground 메서드 내에서 화면 처리가 필요할 때 사용한다.
4. onPostExcute()
- doInBackground 메서드 수행 완료 후 호출.
- Main Thread가 처리한다.
-> 스레드안에서 실행될 코드는 doInBackground() 에 넣어두고 UI에 접근할 코드는 나머지에 넣어둔다.
-> AsyncTask도 스레드를 실행하는 것과 같기 때문에 스레드 안에서 실행될 대부분의 코드는 doInBackground() 안에 들어가있게 되며 중간중간 화면에 표시하기 위한 코드 실행을 위해 onProgressUpdate()가 호출되는 것이다.
-> onProgressUpdate()는 doInBackground()안에서 publishProgress()가 호출될 때마다 자동으로 호출된다.
3. AsyncTaskClass 오버라이딩
1. inner class AsyncTaskClass : AsyncTask<Int, Long, String>()
// 제네릭 타입을 3개 지정해주어야 한다.
// 제네릭1) excute() 매개변수 타입
// 제네릭2) publishProgress() 매개변수 타입
// 제네릭3) doInBackground()의 반환 타입 이자 onPostExcute의 매개변수 타입
2. onCreate()에서 sync.excute() 호출로 AsyncTask 가동.
// execute()의 매개변수는 그대로 doInBackground()의 매개변수로 넘어간다.
3. onPreExecute()
4. doInBackground()
// 화면 처리가 필요하다면.....
5. doInBackground() 에서 publishProgress() 호출.
6. onProgressUpdate()
// publishProgress()의 매개변수가 전달됨 화면 처리.
7. doInBackground()의 작업이 끝나면 반환값을 onPostExecute()에 전달하며 종료.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener { view ->
var time = System.currentTimeMillis()
textView.text = "버튼 클릭 : ${time}"
}
var sync = AsyncTaskClass()
// 1. AsyncTask 가동. execute()의 매개변수는 그대로 doInBackground()의 매개변수로 넘어간다.
sync.execute(10, 20)
}
// 제네릭 타입을 3개 지정해주어야 한다.
// 제네릭1) excute() 매개변수 타입
// 제네릭2) publishProgress() 매개변수 타입
// 제네릭3) doInBackground()의 반환 타입 이자 onPostExcute의 매개변수 타입
inner class AsyncTaskClass : AsyncTask<Int, Long, String>() {
// doInBackground 메서드가 호출되기 전에 딱 한 번 호출되는 메서드. Main Thread가 처리한다.
override fun onPreExecute() {
super.onPreExecute()
textView2.text = " AsyncTask 가동 ";
}
// 일반 Thread에서 처리한다. 네트워크 작업 or 5초 이상 걸리는 작업을 이 메서드에서 처리한다.
// 1. execute()의 매개변수는 그대로 doInBackground()의 매개변수로 넘어간다.
override fun doInBackground(vararg params: Int?): String {
// 2.
// varag params에는 ?가 붙어서 NULL을 허용하지만, 정수 값을 뽑아낼거기 때문에 NULL을 허용하면 안되므로
// NULL을 허용하는 변수를 NULL을 허용하지 않는 변수에 넣고싶을 때는 느낌표2개(!!)을 붙여주면 된다.
var a1 = params[0]!!
var a2 = params[1]!!
for (idx in 0..9) {
SystemClock.sleep(100)
a1++
a2++
// 3.
// 이렇게하면 되긴하는데 WrongThread 경고가 뜬다. 안드로이드는 일반 쓰레드에서 화면 처리를 하면 경고를 보낸다. 따라서 좋은 코드가 아님.
//textView2.text = " ${idx} : ${a1}, ${a2}"
// 4.
// doInBackground() 에서 화면처리를 하려면 onProgressUpdate() 함수가 필요하고, 그 함수는 publishProgress()로 호출할 수 있다.
// publishProgress(varags 변수) 매개변수가 onProgressUpdate(varags 변수)로 전달된다. 값 여러개 전달하면 배열로 만들어져 전달된다.
// 메인쓰레드가 한가할 때 publishProgress()를 호출해준다.
var time = System.currentTimeMillis()
publishProgress(time)
}
return "지존현지"
}
// 4.
// doInBackground 메서드에서 publishProgress 메서드를 호출하면 Main Thread가 처리하는 메서드. doInBackground 메서드 내에서 화면 처리가 필요할 때 사용한다.
override fun onProgressUpdate(vararg values: Long?) {
super.onProgressUpdate(*values)
textView2.text = "Async : ${values[0]}"
}
// 5.
// doInBackground()의 반환 타입이 매개변수로 넘어온다.
// doInBackground 메서드 수행 완료 후 호출. MainThread가 처리한다.
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
textView2.text = result
}
}
4. varag 가변형 매개변수
- 가변형 매개변수. 값을 N개 넘겨주면 N개짜리 배열이 만들어져서 넘어간다.
https://developer.android.com/reference/android/os/AsyncTask.html
'Deperecated > Android_강의' 카테고리의 다른 글
안드로이드 - 안드로이드 4대 구성 요소 - Activity 실행하기 (0) | 2020.02.18 |
---|---|
안드로이드 - RunOnUiThread (0) | 2020.02.18 |
안드로이드 - Handler를 통한 화면 처리 (0) | 2020.02.17 |
안드로이드 - Handler를 이용한 반복 작업 (0) | 2020.02.17 |
안드로이드 - 쓰레드 (0) | 2020.02.14 |