Android advanced exercise-efficient display of Bitmap (processing of Bitmap outside the main UI thread)

Source: Internet
Author: User
Processing bitmap outside the main UI thread BitmapFactory.decode*The series of methods discuss how to efficiently load large images. However, regardless of the source of the image data, these methods should not be used on the main UI thread. Because the time consumed by these methods is unpredictable, the image loading time depends on many factors (network or hard disk read/write speed, image size, the processing capability of the mobile phone CPU, etc ). In a program, as long as one of the image loading tasks blocks the main UI thread, your application will not respond (ANR, cannot interact with the user ), the Android system will display a notification to the user, and the user will choose to close your application, which is a very bad user experience. For this reason, you can use AsyncTaskTo process image loading in a thread outside the main UI thread, but there is another problem. to properly handle the concurrency problem, the following describes how to deal with the two problems using asynctask. AsyncTaskClass provides us with a good way to execute some tasks in threads other than the main UI thread, and return the results of the tasks to the main UI thread. You need to inherit the asynctask class and reload some provided methods to use this asynchronous task method. The following is an example Program
Class bitmapworkertask extends asynctask {private final weakreference imageviewreference; private int DATA = 0; Public bitmapworkertask (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]; retu Rn decodesampledbitmapfromresource (getresources (), data, 100,100);} // once complete, see if imageview is still around and set bitmap. // This method runs on the main UI thread @ override protected void onpostexecute (Bitmap bitmap) {If (imageviewreference! = NULL & bitmap! = NULL) {final imageview = imageviewreference. Get (); If (imageview! = NULL) {imageview. setimagebitmap (Bitmap );}}}}

The weak reference is used to save the imageview object to ensureAsyncTaskThe use of imageview and collection of objects referenced by imageview are not affected. There is no guarantee that the objects referenced by imageview are not recycled when the task is completed. Therefore, you must check whether the object is null in the onpostexecute () method. The imageview object may not exist. For example, before a task ends, the user may have left the current user interface (the activity is destroy) or a configuration item (for example, switching between landscape and landscape ).
Therefore, you must perform necessary checks on the imageview object.

You can directly createAsyncTaskAnd call the execute () method to asynchronously load the image.

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

Processing concurrency issues such as common view components such as listview and gridview. When used together with asynctask, another problem occurs. To improve the memory usage efficiency as much as possible, when you scroll through a component, this type of view component uses its subview cyclically. If each subview triggersAsyncTaskThe associated view is not recycled for another subview. In addition, the execution sequence of asynchronous tasks does not mean that the execution sequence at the end of the task is the same. In combination with these two reasons, this concurrency problem may lead to misplacement when the image is set to the subview. To address this concurrency and dislocation problem, we can let the imageview object store a reference to the recently used asynctask, in this way, we can check whether the task is complete and create a dedicated drawable subclass to store a corresponding asynctask (this asynctask is actually used to load the drawable task ), when the image loading task is still running, you can use this drawable to display a default image. When the task is completed, the drawable will be replaced.

// Stores a corresponding task and acts as a placeholder when the task is still executed. When the task is completed, it is replaced with static class asyncdrawable extends bitmapdrawable {private final weakreference bitmapworkertaskreference; public asyncdrawable (Resources res, Bitmap bitmap, bitmapworkertask) {super (Res, bitmap); Signature = new weakreference (bitmapworkertask);} public bitmapworkertask callback () {return bitmapworkertaskreference. get ();}}

Set a placeholder before running the task. The default image is displayed in imageview.
Public void loadbitmap (INT resid, imageview) {If (cancelpotentialwork (resid, imageview) {final bitmapworkertask task = new bitmapworkertask (imageview ); // mplaceholderbitmap refers to the image object final asyncdrawable = new asyncdrawable (getresources (), mplaceholderbitmap, task) to be displayed by default; imageview. setimagedrawable (asyncdrawable); task.exe cute (resid );}}

   cancelPotentialWorkThe method is used to check whether another task associated with imageview is being executed. If yes, it will be disabled by calling the cancel () method.
Task. Only in a few cases, the image data of the two tasks will be equal. If they are equal, there will be no concurrency problems, and we do not need to do any processing.

Public static Boolean cancelpotentialwork (INT data, imageview) {// obtain the final bitmapworkertask = getbitmapworkertask (imageview) of the task associated with imageview; // If yes, cancel if (bitmapworkertask! = NULL) {final int bitmapdata = bitmapworkertask. Data; If (bitmapdata! = Data) {// cancel previous task bitmapworkertask. cancel (true);} else {// the same work is already in progress return false;} // no task associated with the imageview, or an existing task was canceled return true ;}

Below isGetbitmapworkertask ()Method Definition

Private Static bitmapworkertask getbitmapworkertask (imageview) {// imageview may be recycled if (imageview! = NULL) {final drawable = imageview. getdrawable (); If (drawable instanceof asyncdrawable) {final asyncdrawable = (asyncdrawable) drawable; return asyncdrawable. getbitmapworkertask () ;}} return NULL ;}

Now inonPostExecute()Method, we need to check whether the task has been canceled, and whether the current task is associated with imageview.

Class bitmapworkertask extends asynctask {... @ override protected void onpostexecute (Bitmap bitmap) {// If task canceled, this method is never invoked // Why check here? If (iscancelled () {bitmap = NULL;} If (imageviewreference! = NULL & bitmap! = NULL) {final imageview = imageviewreference. get (); Final bitmapworkertask = getbitmapworkertask (imageview); // determine whether the current task is an associated task if (this = bitmapworkertask & imageview! = NULL) {imageview. setimagebitmap (Bitmap );}}}}

The preceding imageview loading method is applicable to imageListViewAndGridViewFor this type of UI view components, we cangetView()Method callLoadbitmapMethod



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.