Ringster's Techblog

Tech, Mobile, Internet

Bitmap을 UI Thread 외부에서 처리하기 (1) – 일반 View

leave a comment »

지난번에 포스팅한 ImageView에 대용량 Bitmap 효과적으로 로딩하기(여기)에 이어서 이번에는 Bitmap을 UI Thread 외부에서 처리하는 법에 대해 정리해 보았다. 이 역시 Google 개발자 튜토리얼(여기)를 참조하여 작성하였고,  지난번 포스팅과 내용이 연결되므로 기존 포스팅을 먼저 읽은 후 읽기를 추천한다.


만약 Bitmap 이미지의 리소스를 메모리가 아닌 네트워크나, 디스크를 통해서 가져와야 한다면 해당 이미지를 절대 main Thread(UI Thread)에서 가져와서는 안된다. 이는 앱의 반응성을 늦추고, 심한 경우 시스템은 앱이 반응하지 않는다고 판단하여 ANR(Android Not Responding) 메시지를 띄우고 앱을 죽여버린다.

이번 포스팅에서는 이를 방지하기 위해 AsyncTask를 이용하여 background thread에서 작업을 실행한 후 작업 결과를 UI Thread로 돌려주는 방법에 대해 정리한다.

1. AsyncTask 생성하기

AsyncTask가 받아들이는 세 인자는 <Params, Progress, Result>의 순이다. Params의 경우 doInBackground 메소드를 통해 background 작업을 할때 넘겨줄 반환형을, Progress의 경우 onProgressUpdate 메소드를 통해 백그라운드 작업의 진행상황을 출력할 때 필요한 반환형을 Result의 경우 onPostExecute 메소드에서 백그라운드 작업이 끝난 후 결과를 돌려줄 반환형을 의미한다. 자세한 내용은 Android developer 사이트의 (여기)를 참조하자.

 백그라운드에서 이미지 작업을 실행하고, 그 작업한 이미지를 UI 쓰레드에서 출력할 것이므로 인자는 Integer, Void, Bitmap 순으로 넘겨주었고, doInBackground 메소드 안에서는 지난번 포스팅때 작성한 decodeSampledBitmapFromResource 메소드를 사용하였다.

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private int data = 0;

    public BitmapWorkerTask(ImageView imageView) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    // Decode image in background.
    @Override
    protected Bitmap doInBackground(Integer... params) {
        data = params[0];
        return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
    }

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}

여기서 주의할 점은 WeakReference로 선언된 ImageView가 Asynctask가 imageView를 Garbage collecting을 방지하는 것을 막으므로(imageview가 Garbage collecting 되게끔 보장하므로) onPostExecute시에 imageView가 존재하는지 확인해줘야 한다. (유저가 Activity를 떠나거나 configuration change등이 발생할 가능성이 있음.)

2. AsyncTask 사용하기

1번의 과정을 통해 AsyncTask를 작성하였다면 새로운 Task를 생성하고 execute(Params…params)를 통해 실행시키면 된다.

여기서는 loadBitmap이라는 메소드를 작성하여 Task를 생성하고 실행하였다.

public void loadBitmap(int resId, ImageView imageView) {
    BitmapWorkerTask task = new BitmapWorkerTask(imageView);
    task.execute(resId);
}

이 메소드의 호출을 통해서 이미지를 UI Thread에서 벗어나 비동기적으로 출력할 수 있다.

Advertisements

Written by Ringster

2014/11/27 , 시간: 8:57 오전

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중

Jay Jin, Programmer&Designer

Fork my brain because I'm ready to commit

쉐어보드

쉐어메이트에 관한 모든 것

jamesjungkuelee's biotech story

Biotech, entrepreneur, life

Communications as Ikor

기업 위기관리의 모든 것

Charles Pyo Ventures

시도와 실패, 성장의 기록. 2막에서도 계속되는 모험들.

VentureBeat

News About Tech, Money and Innovation

Open API, Cloud, DevOps 와 eBook

Open API, eBook, Cloud, DevOps

Economics of almost everything

Tech, Mobile, Internet

cylee

Tech, Mobile, Internet

gorekun.log

고어쿤로그

Google Developers Korea 블로그

Tech, Mobile, Internet

Android Developers Blog

Tech, Mobile, Internet

최피디의 앱스 개발기

기술, 앱스, SNS, 창업

D2 Blog

Tech, Mobile, Internet

All of Software

Tech, Mobile, Internet

'Startup's Story Platform’

'Startup's Story Platform’

%d 블로거가 이것을 좋아합니다: