Nuke Olaf - Log Store

[Android] 안드로이드 - AsyncTask 예제 사이트 링크 본문

Android

[Android] 안드로이드 - AsyncTask 예제 사이트 링크

NukeOlaf 2019. 12. 30. 20:49
package salix.salix.asyncexample

import android.os.AsyncTask
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import java.lang.Thread.sleep

class MainActivity : AppCompatActivity() {

    private lateinit var task: BackgroundTask
    private var value: Int = 0

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

        // 실행 버튼 이벤트
        executeButton.setOnClickListener {
            // 백그라운드 task 생성
            // AsyncTask 는 한 번 종료되면 재사용이 불가능하다
            // 다시 사용하고 싶으면 해당 AsyncTask 를 재생성해서 사용해야 한다
            task = BackgroundTask()
            // execute 를 통해 백그라운드 task 를 실행시킨다
            // 여기서 매개변수로 100 을 보내는데, doInBackground 에서 사용하게 된다
            task.execute(100)

            // AsyncTask 는 병렬처리가 기본값이 아니라서 한번에 여러개의 AsyncTask 를 실행할 수 없다
            // 동시에 실행한 경우에는 먼저 실행한 AsyncTask 를 끝내고 다음 것을 실행한다
            // 병렬 실행을 위해서는
            /** task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 100)*/
            // 이런 식으로 execute 대신 사용해주면 된다. 
            // 두 번째 매개변수는 넘기는 값으로, 
            // execute 괄호 안의 역할과 똑같다
            // 그러나 이것도 최대 3~4 개 밖에 병렬 실행이 안되며, 더 많은 스레드를 사용하고 싶다면
            // (스레드 10개 사용하고 싶은경우, 10을 인자로 넘김)
            /** var threadPool: ExecutorService = Executors.newFixedThreadPool(10)
            task.executeOnExecutor(threadPool, 100)*/
        }
        // 취소 버튼 이벤트
        cancelButton.setOnClickListener {
            // task 를 종료한다
            // BackgroundTask 의 onCanceled() 가 호출될 것
            // 이미 스레드가 종료된 후에 cancel 하면 아무일도 일어나지 않는다
            // 스레드가 이미 종료되었기 때문
            task.cancel(true)
        }
    }

    // 새로운 Task 의 정의 (AsyncTask)
    // < >안에 들은 자료형은 순서대로 doInBackground, onProgressUpdate, onPostExecute의 매개변수 자료형을 뜻한다.
    // (내가 사용할 매개변수타입을 설정하면된다)
    inner class BackgroundTask : AsyncTask<Int, Int, Int>() {

        // 초기화 단계에서 사용한다. 초기화 관련 코드를 작성한다
        override fun onPreExecute() {
            super.onPreExecute()
            value = 0
            progress.progress = value
        }

        // 스레드의 백그라운드 작업 구현
        // 여기서 매개변수 vararg params 는 params 란 이름의 Int 배열이라고 생각하면 된다
        // 배열이라서 여러개의 값을 받을 수 있다
        // execute(100, 10, 20, 30) 이런식으로 전달 받으면 된다
        override fun doInBackground(vararg params: Int?): Int {
            // isCancelled() -> Task 가 cancel 될 때까지, 즉 취소될때까지 반복한다
            while (!isCancelled) {
                value += 1
                // 위의 onCreate() 에서 호출한 execute(100) 의 100을 사용한다
                // 그냥 value >= 100 이라고 해도 된다
                if (value >= params[0]!!) {
                    break
                } else {
                    // publishProgress() 는 onProgressUpdate() 를 호출하는 함수이다
                    // (그래서 onProgressUpdate 의 매개변수인 int 즉 Integer 값을 보냄)
                    // 이 함수를 통해 백그라운드 스레드 작업을 실행하면서 중간중간 UI 를 업데이트 할 수 있다
                    // 백그라운드에서는 UI 작업을 할 수 없기 때문에 이 함수를 사용한다
                    publishProgress(value)
                }
                try {
                    sleep(100)
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }
            return value
        }

        // UI 관련 작업 ( 백그라운드 실행중에는 이 메소드를 통해 UI 작업을 할 수 있다 )
        // publishProgress(value)의 value 를 값으로 받는다. value 는 배열이기 때문에 여러 개 받을 수 있음
        override fun onProgressUpdate(vararg values: Int?) {
            super.onProgressUpdate(*values)
            progress.progress = values[0]!!
            textView.text = "현재 진행 값 : ${values[0].toString()}"
        }

        // 이 Task 에서 (즉, 이 스레드에서) 수행되던 작업이 종료되었을 때 호출된다
        override fun onPostExecute(result: Int?) {
            super.onPostExecute(result)
            progress.progress = 0
            textView.text = "완료되었습니다"
        }

        // Task 가 취소되었을 때 호출된다
        override fun onCancelled() {
            super.onCancelled()
            progress.progress = 0
            textView.text = "취소되었습니다"
        }
    }

    // https://youngest-programming.tistory.com/11

}

 

출처 https://youngest-programming.tistory.com/11

 

그 외에 다른 참고 사이트들 >>

https://webnautes.tistory.com/1082

https://itmining.tistory.com/7

 

 

Comments