웹사이트 검색

Android AsyncTask 예제 자습서


오늘은 Android AsyncTask에 대해 살펴보겠습니다. 백그라운드에서 추상 AsyncTask를 수행하는 Android 예제 애플리케이션을 개발할 것입니다.

안드로이드 AsyncTask

Android AsyncTask는 Android에서 제공하는 추상 클래스로, 백그라운드에서 무거운 작업을 수행할 수 있는 자유를 제공하고 UI 스레드를 가볍게 유지하여 애플리케이션의 응답성을 높입니다. Android 애플리케이션은 실행 시 단일 스레드에서 실행됩니다. 이 단일 스레드 모델 작업으로 인해 응답을 가져오는 데 시간이 오래 걸리면 애플리케이션이 응답하지 않을 수 있습니다. 이를 방지하기 위해 Android AsyncTask를 사용하여 전용 스레드에서 백그라운드로 무거운 작업을 수행하고 결과를 다시 UI 스레드로 전달합니다. 따라서 Android 애플리케이션에서 AsyncTask를 사용하면 UI 스레드가 항상 응답성을 유지합니다. Android AsyncTask 클래스에서 사용되는 기본 메서드는 다음과 같이 정의됩니다.

  • doInBackground() : 이 메서드는 백그라운드에서 실행해야 하는 코드를 포함합니다. 이 메서드에서는 publishProgress() 메서드를 통해 UI 스레드에 결과를 여러 번 보낼 수 있습니다. 백그라운드 처리가 완료되었음을 알리려면 return 문을 사용하기만 하면 됩니다.
  • onPreExecute() : 이 메서드는 백그라운드 처리가 시작되기 전에 실행되는 코드를 포함합니다.
  • onPostExecute() : 이 메소드는 doInBackground 메소드가 처리를 완료한 후에 호출됩니다. doInBackground의 결과가 이 메서드에 전달됩니다.
  • onProgressUpdate() : 이 메서드는 publishProgress 메서드를 통해 게시되는 doInBackground 메서드에서 진행률 업데이트를 수신하고 이 메서드는 이 진행률 업데이트를 사용하여 UI 스레드를 업데이트할 수 있습니다.

Android AsyncTask 클래스에서 사용되는 세 가지 일반 유형은 다음과 같습니다.

  • Params : 실행 시 작업에 전송되는 매개변수 유형
  • Progress : 백그라운드 계산 중에 게시된 진행 단위의 유형
  • Result : 백그라운드 연산 결과의 타입

Android AsyncTask 예제

AsyncTask를 시작하려면 다음 스니펫이 MainActivity 클래스에 있어야 합니다.

MyTask myTask = new MyTask();
myTask.execute();

위의 스니펫에서는 AsyncTask를 확장하는 샘플 클래스 이름을 사용했고 백그라운드 스레드를 시작하는 데 사용되는 실행 메서드를 사용했습니다. 메모:

  • AsyncTask 인스턴스는 UI 스레드에서 생성 및 호출되어야 합니다.
  • AsyncTask 클래스에서 재정의된 메서드는 절대 호출하면 안 됩니다. 자동으로 호출됩니다
  • AsyncTask는 한 번만 호출할 수 있습니다. 다시 실행하면 예외가 발생합니다.

이 튜토리얼에서는 사용자가 설정한 시간 동안 프로세스를 절전 모드로 전환하는 AsyncTask를 구현합니다.

Android 비동기 작업 프로젝트 구조

Android AsyncTask 예제 코드

xml 레이아웃은 activity_main.xml에 정의되어 있으며 아래에 지정되어 있습니다. activity_main.xml

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/tv_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="10pt"
        android:textColor="#444444"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="9dip"
        android:layout_marginTop="20dip"
        android:layout_marginLeft="10dip"
        android:text="Sleep time in Seconds:"/>
    <EditText
        android:id="@+id/in_time"
        android:layout_width="150dip"
        android:layout_height="wrap_content"
        android:background="@android:drawable/editbox_background"
        android:layout_toRightOf="@id/tv_time"
        android:layout_alignTop="@id/tv_time"
        android:inputType="number"
        />
    <Button
        android:id="@+id/btn_run"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Run Async task"
        android:layout_below="@+id/in_time"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="64dp" />
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="7pt"
        android:layout_below="@+id/btn_run"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

위의 레이아웃에서 사전 정의된 드로어블을 EditText의 테두리로 사용했습니다. MainActivity.java는 다음과 같이 정의됩니다.

package com.journaldev.asynctask;

import android.app.ProgressDialog;
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.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private Button button;
    private EditText time;
    private TextView finalResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        time = (EditText) findViewById(R.id.in_time);
        button = (Button) findViewById(R.id.btn_run);
        finalResult = (TextView) findViewById(R.id.tv_result);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AsyncTaskRunner runner = new AsyncTaskRunner();
                String sleepTime = time.getText().toString();
                runner.execute(sleepTime);
            }
        });
    }

    private class AsyncTaskRunner extends AsyncTask<String, String, String> {

        private String resp;
        ProgressDialog progressDialog;

        @Override
        protected String doInBackground(String... params) {
            publishProgress("Sleeping..."); // Calls onProgressUpdate()
            try {
                int time = Integer.parseInt(params[0])*1000;

                Thread.sleep(time);
                resp = "Slept for " + params[0] + " seconds";
            } catch (InterruptedException e) {
                e.printStackTrace();
                resp = e.getMessage();
            } catch (Exception e) {
                e.printStackTrace();
                resp = e.getMessage();
            }
            return resp;
        }


        @Override
        protected void onPostExecute(String result) {
            // execution of result of Long time consuming operation
            progressDialog.dismiss();
            finalResult.setText(result);
        }


        @Override
        protected void onPreExecute() {
            progressDialog = ProgressDialog.show(MainActivity.this,
                    "ProgressDialog",
                    "Wait for "+time.getText().toString()+ " seconds");
        }


        @Override
        protected void onProgressUpdate(String... text) {
            finalResult.setText(text[0]);
            
        }
    }
}

Android AsyncTask 예제 프로젝트 다운로드