안드로이드 비동기 처리하기 AsyncTask

프로그래밍/Android 2013. 8. 30. 20:11

안드로이드 비동기 처리하기 AsyncTask


비동기 처리를 하기 위해서는 별도의 Thread 를 생성하여 public void run()  메소드를 구현하면 되지만 안드로이드에서는 직접 Thread 를 생성하기 보다는 AsyncTask 를 사용하길 권장합니다.

AsyncTask 내부에는 자체 ThreadPool 이 있어 Thread 가 무한정 늘어나 메모리에 부담을 주지 않도록 관리 하고 있기 때문에

따로 ThreadPool 을 관리하지 않는다면 AsyncTask 를 사용하는게 무난할 것 같습니다.


아래는 비동기적으로 ImageView에 Bitmap을 로드하는 코드입니다.


doInBackground 메소드는 기존의 Thread 에서의 run() 메소드라고 보시면 됩니다.

AsyncTask 는 처리할 데이터에 따라 파라미터 타입을 정의할 수 있습니다. 정의하는 부분은 클래스를 정의하는 부분에 있습니다.

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap>{


 Integer

  execute, doInBackground 의 파라미터 타입

 Void

  onProgressUpdate 의 파라미터 타입

 Bitmap

  doInBackground 의 리턴값, onPostExecute 의 파라미터로 설정됩니다.


AsyncTask 소스를 보면 좀더 정확히 확인하실 수 있습니다.


또한 AsyncTask 는 실행 전후로 전처리, 후처리를 할 수 있는 콜백 메소드를 제공합니다.

onPreExecute(), onPostExecute( Bitmap)


class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap>{

private final WeakReference<ImageView> imageViewReference;

private int data = 0;

public BitmapWorkerTask( ImageView imageView){

// WeakReference 를 사용하는 이유는 image 처럼 메모리를 많이 차지하는 객체에 대한 가비지컬렉터를 보장하기 위해서입니다.

imageViewReference = new WeakReference<ImageView>(imageView);

}

@Override

protected Bitmap doInBackground( Integer... params){

data = param[0];

return decodeSampledBitmapFromResource( getResources(), data, 100, 100);

}

@Override

protected void onPostExecute( Bitmap bitmap){

if( imageReference != null && bitmap != null){

final ImageViewReference imageView = imageViewReference.get();

if( imageView != null){

imageView.setImageBitmap( bitmap);

}

}

}

}


위처럼 AsyncTask 를 확장하는 클래스를 생성한후 실행하면 됩니다.

public void loadBitmap( int resId, ImageView imageView){

BitmapWorkerTask task = new BitmapWorkerTask( imageView);

task.execute( resId);

}


AsyncTask 는 execute( Runnable) 메소드도 제공하기 때문에 별도의 스레드 작업을 할때도 사용할 수 있습니다.

[별도의 카메라 앱을 실행시켜 사진을 촬영하는 코드]

AsyncTask.execute( new Runnable(){

public void run() {

Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

try{

mImageF = createImageFile();

// 이미지가 저장될 파일은 카메라 앱이 구동되기 전에 세팅해서 넘겨준다.

openCameraIntent.putExtra( MediaStore.EXTRA_OUTPUT, Uri.fromFile( mImageF)); 

mActivity.startActivityForResult( openCameraIntent, RequestCodes.REQUESTCODE_CAMERA_PICTURE);

}catch( IOException e){

e.printStackTrace();

}

}

});


: