Asynchronous loading of Android app development Images

Source: Internet
Author: User

As we all know, Android Application Development cannot perform time-consuming operations in the UI thread. Otherwise, an annoying ANR window will pop up.

In application development, if you need to load image resources from the network, disk, or other non-memory, the loading time may be subject to other factors (such as disk, network, image size, CPU, and so on) is easy to produce time-consuming operations. Therefore, do not perform similar operations in the UI thread. Today, I will share with you how to asynchronously load images through asynctask and how to handle multi-thread concurrency issues.

How to Use asynctask to load images?

With aysnctask, you can easily load Resources in the startup background thread and return the results to the UI thread. When using it, you need to create a subclass of it and implement the corresponding method. The following is an example of loading a large image to imageview through aysnctask and decodesampledbitmapfromresource:

 1 class BitmapWorkerTask extends AsyncTask { 2     private final WeakReference imageViewReference; 3     private int data = 0; 4                                                                         5     public BitmapWorkerTask(ImageView imageView) { 6         // Use a WeakReference to ensure the ImageView can be garbage collected 7         imageViewReference = new WeakReference(imageView); 8     } 9                                                                                                                                                                                       10     // Decode image in background.11     @Override12     protected Bitmap doInBackground(Integer... params) {13         data = params[0];14         return decodeSampledBitmapFromResource(getResources(), data, 100, 100));15     }16                                                                                                                                                                                     17     // Once complete, see if ImageView is still around and set bitmap.18     @Override19     protected void onPostExecute(Bitmap bitmap) {20         if (imageViewReference != null && bitmap != null) {21             final ImageView imageView = imageViewReference.get();22             if (imageView != null) {23                 imageView.setImageBitmap(bitmap);24             }25         }26     }27 }

The reason why weakreference is used to save imageview is to ensure that asynctask does not prevent Resource Recycling when memory resources are insufficient. Therefore, the imageview still exists when the task ends, therefore, you should verify it in onpostexecute (in this example, imageview may be recycled if the user closes the activity or the system settings change before the task ends ).

You can load images asynchronously in the following ways:

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

How to handle concurrent operations?

In common view components, such as listview and gridview, the system recycles resources instead of using sub-views when performing the view scrolling operation ,, the above method will introduce another problem when loading images. If asynctask is enabled in each sub-view, it is not guaranteed that the related view has been recycled when the task is completed. In addition, they cannot guarantee the order of loading completion.

We can save the asynctask reference to imageview and associate it with drawable. When the task is completed, check whether the reference exists.

Create a dedicated drawable subclass to store references to the job thread. In this way, the image can be set in imageview when the task is completed.

 1 static class AsyncDrawable extends BitmapDrawable { 2     private final WeakReference bitmapWorkerTaskReference; 3     public AsyncDrawable(Resources res, Bitmap bitmap, 4             BitmapWorkerTask bitmapWorkerTask) { 5         super(res, bitmap); 6         bitmapWorkerTaskReference = 7             new WeakReference(bitmapWorkerTask); 8     } 9                                                                  10     public BitmapWorkerTask getBitmapWorkerTask() {11         return bitmapWorkerTaskReference.get();12     }13 }

Before executing bitmaptask, you can create asyncdrawable and bind it to imageview.

1 public void loadBitmap(int resId, ImageView imageView) {2     if (cancelPotentialWork(resId, imageView)) {3         final BitmapWorkerTask task = new BitmapWorkerTask(imageView);4         final AsyncDrawable asyncDrawable =5                 new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);6         imageView.setImageDrawable(asyncDrawable);7         task.execute(resId);8     }9 }

In the code above, cancelpotentialwork is used to determine whether a running task is bound to imageview. If yes, cancel the task by executing the cancel method. Of course, this situation does not often occur,

The implementation of cancelpotentialwork is as follows:

 1 public static boolean cancelPotentialWork(int data, ImageView imageView) { 2     final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); 3                4     if (bitmapWorkerTask != null) { 5         final int bitmapData = bitmapWorkerTask.data; 6         if (bitmapData != data) { 7             // Cancel previous task 8             bitmapWorkerTask.cancel(true); 9         } else {10             // The same work is already in progress11             return false;12         }13     }14     // No task associated with the ImageView, or an existing task was cancelled15     return true;16 }

The following is an auxiliary method for finding the associated asynchronous task through imageview;

 1 private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { 2    if (imageView != null) { 3        final Drawable drawable = imageView.getDrawable(); 4        if (drawable instanceof AsyncDrawable) { 5            final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; 6            return asyncDrawable.getBitmapWorkerTask(); 7        } 8     } 9     return null;10 }

In the next step, you must update onpostexecute in bitmapworkertask,

First, check whether the task is canceled, such as modifying the associated imageview:

 1 class BitmapWorkerTask extends AsyncTask { 2     ...                                                                                                                                     3     @Override 4     protected void onPostExecute(Bitmap bitmap) { 5         if (isCancelled()) { 6             bitmap = null; 7         }                                                                                                                              8         if (imageViewReference != null && bitmap != null) { 9             final ImageView imageView = imageViewReference.get();10             final BitmapWorkerTask bitmapWorkerTask =11                     getBitmapWorkerTask(imageView);12             if (this == bitmapWorkerTask && imageView != null) {13                 imageView.setImageBitmap(bitmap);14             }15         }16     }17 }

With the preceding method, you can use it in listview, gridview, or other components with sub-view recycle processing.

Loadbitmap you can easily add images to imageview, for example, call the getview method in the adapter of girdview.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.