1. AsyncTask

핸들러를 사용하면 스레드를 사용하면서 UI 객체에 접근이 가능하지만, 

스레드 안에서 실행되는 코드와 핸들러 안에서 실행되는 코드가 구분되어야 하기 때문에 복잡하다.

AsyncTask를 이용하면 하나의 클래스 안에 스레드로 동작하는 부분과 UI 객체에 접근하는 부분을 함께 넣어 둘 수 있다.

즉, 하나의 작업 단위가 하나의 클래스로 만들어 질 수 있다.


onPreExecute()

doInBackground() 메서드가 호출되기 전에 onPreExcuted() 메서드가 호출된다.

스레드 작업 이전에 수행할 동작을 수행한다. 


doInBackground() 

스레드 안에서 실행될 코드를 작성한다.


onProgressUpdate()

UI에 접근할 코드를 작성한다.

doInBackground()에서 publicProgress() 메서드를 호출할 때마다 onProgressUpdate가 자동 호출된다.

전달 받은 데이터를 이용해서 중간중간 UI 업데이트를 한다.


onPostExecute()

UI에 접근할 코드를 작성한다.

모든 과정이 끝나고 나면, 즉 doInBackground() 메서드의 결과 값을 리턴받으면 onPostExecute() 메서드가 호출된다.




2. 구현 결과 화면

    



3. activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <ProgressBar
        android:id="@+id/progress_bar"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:progressBackgroundTint="@android:color/holo_blue_light"
        android:progressTint="@color/colorAccent"
        android:max="100"
        android:secondaryProgress="100"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
 
    <Button
        android:id="@+id/button"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:text="시작"
        android:textSize="20sp"
        app:layout_constraintTop_toBottomOf="@id/progress_bar"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
 
</android.support.constraint.ConstraintLayout>
 
cs



4. MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.tistory.qlyh8.pracitice;
 
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity  {
 
    ProgressBar progressBar;
    Button button;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        progressBar = findViewById(R.id.progress_bar);
 
        button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
             ProgressTask task = new ProgressTask();
             task.execute("시작");    // AsyncTask 실행
            }
        });
    }
 
    // 첫 번째 String 은 doInBackground(), 두 번째 Integer 는  onProgressUpdate(),
    // 세 번째 Integer 는 onPostExecute() 메서드의 타입을 지정한다.
    class ProgressTask extends AsyncTask<String, Integer, Integer>{
        int value = 0;
 
        // 가변길이 문자열 파라미터를 통해 몇 개의 문자열이건 전달해 줄 수 있다.
        @Override
        protected Integer doInBackground(String... strings) {
            while(true){
                if(value > 100)
                    break;
 
                value += 1;
                publishProgress(value);
 
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return value;
        }
 
        //  publishProgress()의 파라미터 타입과 onProgressUpdate()의 파라미터 타입이 같다.
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            progressBar.setProgress(values[0]);
        }
 
        // doInBackground() 결과 값의 타입과 onPostExecute()의 파라미터 타입이 같다.
        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);
            Toast.makeText(getApplicationContext(), "완료", Toast.LENGTH_LONG).show();
        }
    }
}
cs



5. 참고

- ProgressBar | Android Developers

https://developer.android.com/reference/android/widget/ProgressBar

- AsyncTask | Android Developers

https://developer.android.com/reference/android/os/AsyncTask

- 프로세스 및 스레드 | Android Developers

https://developer.android.com/guide/components/processes-and-threads




출처: https://www.edwith.org/boostcourse-android/lecture/17087/

+ Recent posts