Outside the UI thread, multithreading bitmaps

Source: Internet
Author: User

Multithreaded processing bitmaps
In a previous article, we discussed:Android effectively handles bitmap and reduces memory, but it's best not to do it on the main thread (UI thread) if the picture is local or network or somewhere else. Picture loading time is related to many factors (such as the speed of reading from the network or local, the size of the picture, the ability of the CPU), and if these tasks block the UI thread, the system may recycle and close it ( see Designing for responsiveness For more information). in this article we will discuss how to use asynchronous tasks (Asynctask) to add bitmap (images of local or network pictures or other resources) outside the UI thread, and how you can handle them concurrently. Original address:http://wear.techbrood.com/training/displaying-bitmaps/process-bitmap.html
using asynchronous Tasks  asynchronous tasks provide a convenient way to implement the interaction between the UI thread and the background thread. We can derive a class and rewrite his method. Here's an example of loading a large map to ImageView, using the technology of the previous articledecodesampledbitmapfromresource (Please see the contents of this article http://blog.csdn.net/liu8497/article/details/40786721):
Class Bitmapworkertask extends Asynctask<integer, Void, bitmap> {private Final weakreference<imageview> IM    Ageviewreference;    private int data = 0; Public Bitmapworkertask (ImageView ImageView) {//Use a weakreference to ensure the ImageView can is garbage collec    Ted 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); }        }    }}

Using WeakReferenceto save ImageView in order to recover their memory well, but there is no guarantee that when the asynchronous task ends, the ImageView still exists, so it must beOnPostExecute () checks whether it is empty. The ImageView may be empty, for example, before the asynchronous task exits, when the activity exits or when other configurations change
start loading a bitmap only needs to instantiate a task and execute it:
public void LoadBitmap (int resId, ImageView ImageView) {    bitmapworkertask task = new Bitmapworkertask (ImageView); 
   task.execute (resId);}

Parallel Processinggeneral components, such as the ListView and GridView, introduce additional issues when combined with asynchronous tasks. In order to use memory better, the user starts to recycle other sub-view when scrolling. If each child view uses an asynchronous task, we cannot guarantee that the associated view will not be reclaimed when the asynchronous task ends. We also cannot guarantee that asynchronous tasks are executed in our order. There is a blog multithreading for Performance, which discusses the problem of parallel processing in depth, and provides a workaround that ImageView point to the most recent asynchronous task and can verify execution after the task is finished. Using the same approach, the above mentioned async tasks can follow a similar route. Create a dedicated drawable to store resources that point to the task. So, we use bitmapdrawable so that at the end of the task our image is displayed in ImageView:
Static Class Asyncdrawable extends Bitmapdrawable {    private final weakreference<bitmapworkertask> bitmapworkertaskreference;    Public Asyncdrawable (Resources res, Bitmap Bitmap,            bitmapworkertask bitmapworkertask) {        super (res, Bitmap);        Bitmapworkertaskreference =            new weakreference<bitmapworkertask> (Bitmapworkertask);    }    Public Bitmapworkertask Getbitmapworkertask () {        return bitmapworkertaskreference.get ();    }}
In the execution  BitmapWorkerTask之前,我们可以给ImageView绑定一个AsyncDrawable。
public void LoadBitmap (int resId, ImageView ImageView) {    if (cancelpotentialwork (ResId, ImageView)) {        final Bitmapworkertask task = new Bitmapworkertask (imageView);        Final asyncdrawable asyncdrawable =                new Asyncdrawable (Getresources (), Mplaceholderbitmap, Task);        Imageview.setimagedrawable (asyncdrawable);        Task.execute (resId);    }}

   cancelpotentialworkThis method checks to see if there are other tasks associated with the ImageView. If so, we use function Cancel () to cancel out the associated task. In rare cases, the data for the new task matches and interacts with the previous. Below iscancelpotentialworkImplementation of:
public static Boolean cancelpotentialwork (int data, ImageView ImageView) {    final bitmapworkertask bitmapworkertask = Getbitmapworkertask (ImageView);    if (bitmapworkertask! = null) {        final int bitmapData = Bitmapworkertask.data;        If BitmapData is not yet set or it differs from the new data        if (BitmapData = = 0 | | BitmapData! = data) {            //Ca  Ncel Previous Task            bitmapworkertask.cancel (TRUE);        } else {            //the same work was already in progress            return false;        }    }    No task associated with the ImageView, or a existing task was cancelled    return true;}

An auxiliary methodGetbitmapworkertask ()To retrieve the tasks associated with the ImageView.
private static Bitmapworkertask Getbitmapworkertask (ImageView ImageView) {   if (ImageView! = null) {       final drawable drawable = imageview.getdrawable ();       if (drawable instanceof asyncdrawable) {           final asyncdrawable asyncdrawable = (asyncdrawable) drawable;           return Asyncdrawable.getbitmapworkertask ();       }    }    return null;}
One final stepOnPostExecute ()In the Bitmapworkertask update in order to verify whether the task is canceled and verify that the current task matches the ImageView:
Class Bitmapworkertask extends Asynctask<integer, Void, bitmap> {    ...    @Override    protected void OnPostExecute (Bitmap Bitmap) {        if (iscancelled ()) {            Bitmap = null;        }        if (imageviewreference! = null && bitmap! = null) {            final ImageView ImageView = Imageviewreference.get ();            Final Bitmac91pworkertask bitmapworkertask =                    getbitmapworkertask (imageView);            if (this = = Bitmapworkertask && ImageView! = null) {                imageview.setimagebitmap (bitmap);}}}    
Now we can use asynchronous tasks to recycle resources more efficiently within the ListView and GridView or other components. We just need to execute loadBitmapMethod can put a picture into the imageview inside. For example, in the GridView, we use this method in the GetView method of adapter.



  

Outside the UI thread, multithreading bitmaps

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.