Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android AsyncTask 완벽 가이드: 핵심 개념과 이미지 다운로드 실전 예제

AsyncTask란 무엇인가?

Android의 AsyncTask는 백그라운드 스레드에서 작업을 처리하고, 그 결과를 메인(UI) 스레드에 안전하게 반영하기 위한 클래스입니다. Android 개발에서는 백그라운드 스레드가 직접 UI를 조작할 수 없기 때문에, 두 스레드 간의 통신을 돕는 도구가 반드시 필요합니다. AsyncTask는 이러한 통신 과정을 손쉽게 구현할 수 있도록 도와줍니다.

참고: AsyncTask는 API 레벨 30(Android 11)부터 공식적으로 지원 중단(deprecated)되었습니다. 신규 프로젝트에서는 Kotlin Coroutines, WorkManager, Executor 등을 사용하는 것이 권장되지만, 기존 코드 유지보수나 학습 목적으로 여전히 이해할 가치가 있습니다.

AsyncTask의 주요 메서드

  • onPreExecute() — 백그라운드 작업이 시작되기 전에 호출됩니다. 사용자에게 프로그레스바나 로딩 애니메이션을 보여주는 등 사전 준비 작업을 처리하기에 적합합니다. 물론 doInBackground()만 단독으로 호출해도 동작하지만, 모든 AsyncTask 메서드를 함께 사용하는 것이 모범 사례(best practice)입니다.

  • doInBackground(Params) — 백그라운드 스레드에서 실제 작업이 수행되는 핵심 메서드입니다. 이 메서드 내부에서는 UI 스레드와 관련된 활동(Activity)이나 프래그먼트(Fragment)를 직접 건드리면 안 됩니다.

  • onProgressUpdate(Progress...) — 백그라운드 작업 진행 중에 UI에 정보를 갱신해야 할 때 사용합니다. 예를 들어 다운로드 진행률을 표시할 수 있습니다.

  • onPostExecute(Result) — 백그라운드 작업이 완료된 후 그 결과를 받아 UI를 최종적으로 업데이트하는 메서드입니다.

AsyncTask의 제네릭 타입

  • TypeOfVarArgParams — execute() 호출 시 전달되는 파라미터의 타입을 정의합니다.

  • ProgressValue — 작업 진행 상황을 나타내는 단위의 타입입니다. 백그라운드 작업 중 onProgressUpdate()를 통해 UI에 진행 정보를 전달할 때 사용됩니다.

  • ResultValue — 백그라운드 작업 완료 후 반환되는 결과값의 타입을 정의합니다.

이번 예제에서는 Android에서 AsyncTask를 활용해 인터넷에서 이미지를 다운로드하고 화면에 표시하는 방법을 단계별로 살펴보겠습니다.

1단계 — 새 프로젝트 생성

Android Studio에서 File → New Project를 선택하고, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.

2단계 — 레이아웃 파일 작성

res/layout/activity_main.xml에 아래 코드를 추가합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:tools = "https://schemas.android.com/tools"
    android:id = "@+id/rootview"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:orientation = "vertical"
    android:background = "#c1c1c1"
    android:gravity = "center_horizontal"
    tools:context = ".MainActivity">
<Button
    android:id = "@+id/asyncTask"
    android:text = "Download"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content" />
<ImageView
    android:id = "@+id/image"
    android:layout_width = "300dp"
    android:layout_height = "300dp" />
</LinearLayout>

위 XML에는 버튼 하나와 ImageView가 배치되어 있습니다. 사용자가 버튼을 클릭하면 이미지가 다운로드되어 ImageView에 표시됩니다.

3단계 — MainActivity.java 작성

src/MainActivity.java에 아래 코드를 추가합니다.

package com.example.andy.myapplication;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
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.ImageView;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
    URL ImageUrl = null;
    InputStream is = null;
    Bitmap bmImg = null;
    ImageView imageView= null;
    ProgressDialog p;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button=findViewById(R.id.asyncTask);
        imageView=findViewById(R.id.image);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AsyncTaskExample asyncTask=new AsyncTaskExample();
                asyncTask.execute("https://www.tutorialspoint.com/images/tp-logo-diamond.png");
            }
        });
    }
    private class AsyncTaskExample extends AsyncTask<String, String, Bitmap> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            p = new ProgressDialog(MainActivity.this);
            p.setMessage("Please wait...It is downloading");
            p.setIndeterminate(false);
            p.setCancelable(false);
            p.show();
        }
        @Override
        protected Bitmap doInBackground(String... strings) {
            try {
                ImageUrl = new URL(strings[0]);
                HttpURLConnection conn = (HttpURLConnection) ImageUrl.openConnection();
                conn.setDoInput(true);
                conn.connect();
                is = conn.getInputStream();
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                bmImg = BitmapFactory.decodeStream(is, null, options);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bmImg;
        }
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if(imageView!=null) {
                p.hide();
                imageView.setImageBitmap(bitmap);
            }else {
                p.show();
            }
        }
    }
}

위 코드에서는 AsyncTask를 통해 이미지를 다운로드하고, 완료된 비트맵을 ImageView에 설정합니다. 작업이 시작되기 전에는 onPreExecute()에서 ProgressDialog가 표시되며, 다운로드가 끝나면 onPostExecute()에서 다이얼로그를 숨기고 이미지를 화면에 나타냅니다.

4단계 — 매니페스트에 인터넷 권한 추가

manifest.xml에 아래 코드를 추가합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "https://schemas.android.com/apk/res/android"
package = "com.example.andy.myapplication">
    <uses-permission android:name = "android.permission.INTERNET"/>
    <application
        android:allowBackup = "true"
        android:icon = "@mipmap/ic_launcher"
        android:label = "@string/app_name"
        android:roundIcon = "@mipmap/ic_launcher_round"
        android:supportsRtl = "true"
        android:theme = "@style/AppTheme">
        <activity android:name = ".MainActivity">
            <intent-filter>
                <action android:name = "android.intent.action.MAIN" />
                <category android:name = "android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

AndroidManifest.xml 파일에 인터넷 권한(android.permission.INTERNET)을 추가해야 이미지를 네트워크에서 내려받을 수 있습니다.

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 기기를 컴퓨터에 연결한 상태라고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바의 Run 아이콘을 클릭하세요. 목록에서 자신의 모바일 기기를 선택하면 앱이 설치되고 기본 화면이 표시됩니다.

Android AsyncTask 완벽 가이드: 핵심 개념과 이미지 다운로드 실전 예제

Download 버튼을 누르면 UI에 진행 상태가 표시되면서 백그라운드에서 이미지가 다운로드됩니다.

Android AsyncTask 완벽 가이드: 핵심 개념과 이미지 다운로드 실전 예제

다운로드가 완료되면 결과 이미지가 UI에 자동으로 갱신되어 표시됩니다.

Android AsyncTask 완벽 가이드: 핵심 개념과 이미지 다운로드 실전 예제

마무리

지금까지 AsyncTask의 구조와 주요 메서드, 제네릭 타입을 알아보고, 실제 이미지 다운로드 예제를 통해 백그라운드 작업과 UI 업데이트를 연동하는 방법을 살펴보았습니다. AsyncTask는 간단한 비동기 작업에 유용하지만 현재는 지원이 중단된 만큼, 새 프로젝트에서는 Coroutines나 WorkManager 같은 최신 대안을 검토해 보시기 바랍니다.