본문 바로가기
Android/Concepts

AsyncTask 사용법

by JuHy_ 2020. 4. 23.

AsyncTask란?

Thread를 사용할 때는 UI 객체에 접근하기 위해서는 Handler를 통해 접근해야 한다.

하지만 AsyncTask를 사용하면 하나의 클래스 안에 Thread 동작 부분과 UI 접근 부분을 동시에 정의할 수 있다.

따라서 Thread에 비해 하나의 작업 단위를 하나의 클래스로 정의할 수 있다는 장점이 있다.

 

사용법

AsyncTask 클래스를 상속받아 클래스를 정의할 때는, 다음과 같은 메소드들을 정의해준다.

 

1. doInBackground()

AsyncTask를 시작하면 자동으로 실행되는 코드 부분 (Thread 부분)

 

2. onProgressUpdate()

AsyncTask가 동작하는 중간중간 상태를 업데이트 하는 부분 (주로 UI 업데이트에 사용)

 

3. onPostExecute()

AsyncTask가 종료되면(doInBackground 코드가 모두 실행되면) 실행되는 부분

 

위의 함수들이 호출되는 과정을 간단히 살펴보자.

 

처음 AsyncTask가 시작되면 doInBackground 내부의 코드가 실행된다.

코드를 실행하는 중 doInBackground 내부에서 중간중간 업데이트를 위해 publishProgress() 함수를 호출하면 onProgressUpdate가 실행되어 UI 부분을 업데이트 하는 등의 필요한 기능을 수행한다.

마지막으로 doInBackground 내부의 코드가 모두 실행되면 onPostExecute() 함수가 호출된다.

 

따라서 각각의 파라미터는 다음과 같이 전달된다.

 

- onCreate()

task.execute(String) → doInBackground(String)

 

- doInBackground()

publishProgress(Integer) → onProgressUpdate(Integer)

return value(Integer) → onPostExecute(Integer)

 

이제 실제로 구현해보자.

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Thread Start" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_above="@+id/button_start"
        android:layout_marginBottom="100dp"
        android:layout_centerHorizontal="true" />

</RelativeLayout>
package com.juhy.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        progressBar = findViewById(R.id.progressBar);

        Button button_start = findViewById(R.id.button_start);
        button_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ProgressTask task = new ProgressTask();
                task.execute("Start");
            }
        });

    }

    class ProgressTask extends AsyncTask<String, Integer, Integer> {

        int value = 0;

        @Override
        protected Integer doInBackground(String... strings) {
            while(true){
                if(value >= 100)
                    break;

                value += 4;

                publishProgress(value);

                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            return value;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);

            progressBar.setProgress(values[0].intValue());
        }

        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);

            Toast.makeText(getApplicationContext(), "Complete", Toast.LENGTH_LONG).show();
        }

    }

}

doInBackground()에서는 200ms마다 value 값을 4씩 늘려주다가 100이 넘으면 종료한다.

(ProgressBar의 최대 진행도가 100이기 때문에 100이 넘으면 반복문을 종료되도록 함)

(value 값은 1씩 증가시키면 너무 느려 4씩 증가시켰음)

 

이 때, 값을 늘려준 뒤에는 publishProgress() 함수를 통해 정수값을 넘겨주어 ProgressBar를 업데이트한다.

 

value 값이 100이 넘으면 while문이 끝나고 doInBackground()가 종료된 뒤 onPostExecute()에서 Toast를 띄워준다.

 

 

실행해보면 정상적으로 ProgressBar가 진행된 뒤 종료되며 Toast가 나타나는 것을 볼 수 있다.

 

 

Reference

[부스트코스]안드로이드 프로그래밍

https://www.edwith.org/boostcourse-android