Displaying Bitmaps Efficiently(2)-Processing Bitmaps Off the UI Thread

来源:互联网 发布:单片机编程用什么语言 编辑:程序博客网 时间:2024/06/05 04:57

The BitmapFactory.decode* methods, discussed in theLoad Large Bitmaps Efficiently lesson, should not be executed on the main UI thread if the source data is read from disk or a network location (or really any source other than memory). The time this data takes to load is unpredictable and depends on a variety of factors (speed of reading from disk or network, size of image, power of CPU, etc.). If one of these tasks blocks the UI thread, the system flags your application as non-responsive and the user has the option of closing it (seeDesigning for Responsiveness for more information).

This lesson walks you through processing bitmaps in a background thread usingAsyncTask and shows you how to handle concurrency issues.

为防止从disk或network获取数据时延迟导致UI线程的阻塞,我们使用AsyncTask来处理图片展示。

Use an AsyncTask


The AsyncTask class provides an easy way to execute some work in a background thread and publish the results back on the UI thread. To use it, create a subclass and override the provided methods. Here’s an example of loading a large image into anImageView usingAsyncTask anddecodeSampledBitmapFromResource():

class BitmapWorkerTask extends AsyncTask {    private final WeakReference imageViewReference;    private int data = 0;    public BitmapWorkerTask(ImageView imageView) {        // Use a WeakReference to ensure the ImageView can be garbage collected        imageViewReference = new WeakReference(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);            }        }    }}

The WeakReference to theImageView ensures that theAsyncTask does not prevent theImageView and anything it references from being garbage collected. There’s no guarantee theImageViewis still around when the task finishes, so you must also check the reference inonPostExecute(). TheImageViewmay no longer exist, if for example, the user navigates away from the activity or if a configuration change happens before the task finishes.

这里使用WeakReference来持有ImageView,这样就不会阻止别的地方对ImageView对象的释放;所以当在AsyncTask中使用ImageView时我们要先判断ImageView是否为空。

To start loading the bitmap asynchronously, simply create a new task and execute it:

public void loadBitmap(int resId, ImageView imageView) {    BitmapWorkerTask task = new BitmapWorkerTask(imageView);    task.execute(resId);}
原创粉丝点击