본문 바로가기

Android/AsyncTask 3

Android AsyncTask example

안드로이드에서 Thread 대신 AsyncTask를 이용하여 백그라운드 작업 및 UI 갱신 작업 정의하기

시작버튼을 누르면 ImageView에 2개의 이미지가 교대로 출력되고 중지 버튼을 누르면 멈추는 내용

main.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#FF4444CC" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="onBtnStart" android:text="START" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="onBtnStop" android:text="STOP" /> </LinearLayout> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> </LinearLayout>


ThreadDemo.java

package my.android.test; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.EditText; public class ThreadDemo extends Activity { ImageView imageView1; boolean isRunning; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imageView1 = (ImageView) this.findViewById(R.id.imageView1); } public void onBtnStart() { isRunning = true; new IncrementTask(this).execute();//아규먼트는 diInBackground()으로 전달됨 }

public void onBtnStop(View v) { isRunning = false; }

@Override protected void onStop() { super.onStop(); isRunning = false; }

/*내부 클래스로 AsyncTask 를 선언함, Eclipse를 이용하면 오버라이드하는 메소드의 파라미터 타입이나 리턴타입을 자동으로 설정할 수 있기 때문에 그리 복잡하지 않다.

첫번재 파라미터 타입인 Void는 doInBackground()에 전달될 자료형을 의미하며, execute()에서 전달된 자료형과 일치해야 한다.

두번째 파라미터 타입인 Integer는 publishProgress()를 거쳐 onProgressUpdate()에 전달할 자료형을 의미한다.

세번째 파라미터 타입인 Void는 doInBackground()의 리턴타입을 정의하고 이 타입은 onPostExecute()으로 전달된다

*/ class IncrementTask extends AsyncTask<Void, Integer, Void> { Context ctx; IncrementTask(Context ctx) { this.ctx = ctx; } @Override /* 백그라운드 쓰레드에 의해 호출됨. publishProgress()의 아규먼트는 위의 Integer와 동일형 */ protected Void doInBackground(Void... params) { int id = 0;

while( isRunning ) { if(id==R.drawable.ic_launcher) id=R.drawable.mountain; else id=R.drawable.ic_launcher; publishProgress(id); SystemClock.sleep(1000); }

return null; } @Override 

/* 시스템의 UI 쓰레드에 의해 호출되므로 UI갱신이 가능함. publishProgress()의 아규먼트가 결국 이곳까지 전달됨 */ protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); imageView1.setImageResource(values[0]); } @Override 

/* 시스템의 UI 쓰레드에 의해 호출되므로 UI갱신이 가능함, 백그라운드 쓰레드 종 료시에 호출됨. doInBackground()의 리턴값이 이곳으로 전달됨 */ protected void onPostExecute(Void result) { super.onPostExecute(result); Toast.makeText(ctx, "백그라운드 작업완료", Toast.LENGTH_SHORT).show(); } } /* 내부클래스 끝 */ }