매우 오래 걸리는 작업을 해야하는 상황이라고 가정하자.
작업을 순차적으로 진행한다.
따라서 해당 작업이 끝나기 전까지는 다른 작업을 수행할 수 없다.
Thread를 만들어서 매우 오래 걸리는 작업을 Thread가 따로 처리하도록 한다.
따라서 그동안 Main Thread는 다른 작업을 수행할 수 있다.
안드로이드에서 Async를 다루는 방법이다.
현재는 AsyncTask가 deprecated 되었고, rxJava나 coroutine 등으로 대체할 수 있다고 한다. 이에 대한 내용은 따로 블로그를 작성하여 올릴 예정이다.
class BackgroundAsyncTask(): AsyncTask<Params, Progress, Result>(){
}
- Params : doInBackground의 파라미터 타입
- Progress : onProgressUpdate의 파라미터 타입
- Result : onPostExecute의 파라미터 타입
onPreExecute(), onProgressUpdate(), onPostUpdate()는 MainThread에서 수행되기 때문에 UI 객체에 접근할 수 있다.
package com.example.myapplication
import android.os.AsyncTask
import android.os.Bundle
import android.widget.Button
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class AsyncActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_async)
val startButton : Button = findViewById(R.id.button_start)
val stopButton : Button = findViewById(R.id.button_stop)
val progressBar : ProgressBar = findViewById(R.id.progress_bar)
val progressText : TextView = findViewById(R.id.ment)
var task : BackgroundAsyncTask? = null
startButton.setOnClickListener {
task = BackgroundAsyncTask(progressBar, progressText)
task?.execute()
}
stopButton.setOnClickListener {
task?.cancel(true)
}
}
}
// AsyncTask 만들기
class BackgroundAsyncTask(
val progressBar : ProgressBar,
val progressText: TextView
): AsyncTask<Int, Int, Int>(){
var percent: Int = 0
override fun onPreExecute() {
percent = 0 // 처음에는 percent가 무조건 0이어야 한다.
progressBar.progress = percent // progressBar 갱신
}
// thread가 할 작업
override fun doInBackground(vararg params: Int?): Int {
while(isCancelled() == false){
percent++
if(percent>100){
break
}else{
publishProgress(percent) // 이게 실행되면 onProgressUpdate에 percent가 넘어간다
}
try{
Thread.sleep(100) // 0.1초 delay
}catch (e : Exception){
e.printStackTrace()
}
}
return percent // 100퍼센트가 되면 percent 리턴
}
override fun onProgressUpdate(vararg values: Int?) {
progressBar.progress = values[0] ?: 0 // progress 값 갱신
progressText.text = "퍼센트 : " + values[0]
super.onProgressUpdate(*values)
}
override fun onPostExecute(result: Int?) {
progressText.text = "작업이 완료되었습니다."
}
override fun onCancelled(result: Int?) {
super.onCancelled(result)
}
// task가 인위적으로 취소되었을 때
override fun onCancelled() {
progressBar.progress = 0
progressText.text = "작업이 취소되었습니다."
}
}