Image processing for Android Development (III): Asynchronous loading of multiple images with threadpoolexcutor thread pool

Source: Internet
Author: User

On the topic of image processing for Android Development (ii): Using Asynctask and callback interfaces to implement asynchronous loading and compression of images we implemented a large load of the ListView picture. Today, we do this in a different way, using a thread pool.

We need to prepare two things:

1. Picture Download Task Class

2, thread pool.


1, Picture download task class.The picture download task class will need to display the Iamgeview, thread communication message Manager handler to be encapsulated. When the picture download succeeds or fails, handler sends the corresponding message, and the incoming Iamgeview displays the corresponding picture. This is not the application of soft-reference technology, the adoption of the Bitmapmanager is the use of Weakhashmap to implement the cache. About Weakhashmap, is the use of weak reference technology, the implementation of the principle of everyone can go to consult, here is not described in detail.
/** * @ClassName: Asyncimagetask * @author victor_freedom ([email protected]) * @createddate 2015-2-1 pm 10:58:52 * @D Escription: Picture Asynchronous Load Task */public class Asyncimagetask implements Runnable {private final String TAG = "asyncimagetask";//Task label ID, in fact, is the picture cache path private string taskid;//incoming need to set imageviewprivate ImageView imageview;//picture Download path private string desturl;// Download failed display picture of idprivate int failimage = -1;//default picture idprivate int defaultimage = -1;//compression ratio private int samplesize = 1;//set to BAC Kgroundprivate Boolean forbackground = false;private Boolean canceled = false;//message Manager Private Asynchandler handler = null; Animation private Animation Animation = null;public final static int OK = 1;public final static int FAIL = 2;public final Stati            c int exsit = 3;private Boolean forhome = false;/** * constructor * * @param imageView * imageView * @param URL * Picture address */public Asyncimagetask (ImageView ImageView, String URL) {This (null, ImageView, URL);} /** * Constructor * * @param taskId * Task ID * @Param ImageView * imageView * @param URL * Picture address */public Asyncimagetask (String taskId, ImageView ima Geview, String URL) {if (null = = TaskId | | Taskid.trim (). Length () = = 0) {//task ID use picture cache address to identify unique String tid = Cachename.getcach Epath (Imageview.getcontext (), url); this.taskid = tid;} else {this.taskid = taskId;} if (null! = ImageView) {This.imageview = Imageview;this.imageview.settag (This.taskid);} This.desturl = Url;this.handler = new Asynchandler ();} /** * taskId * * @return the taskId */public String gettaskid () {return taskId;} /** * @param taskId * The taskId to set */public void Settaskid (String taskId) {this.taskid = taskId;} /** * Forhome * * @return the Forhome */public boolean isforhome () {return forhome;} /** * @param forhome * The forhome to set */public void Setforhome (Boolean forhome) {this.forhome = Forhome;} /** * defaultimage * * @return the defaultimage */public int getdefaultimage () {return defaultimage;}    /** * @param defaultimage *        The defaultimage to set */public void setdefaultimage (int defaultimage) {this.defaultimage = Defaultimage;} /** * Get download failed display picture Resource ID * * @return int */public int getfailimage () {return failimage;} /** * Set to display picture resource ID after download failure * * @param failimage * r.drawable.xxx */public void setfailimage (int failimage) {THIS.F Ailimage = Failimage;} /** * Get Picture Compression ratio * * @return int */public int getsamplesize () {return samplesize;} /** * Set the sample rate of the picture * * @param samplesize * Preferably 2 of the number of times */public void setsamplesize (int samplesize) {if (SampleSize &G T 0) {this.samplesize = SampleSize;}} /** * Whether the image is set as background image after download * * @return is the background graph returns true, otherwise returns false */public Boolean Isforbackground () {return forbackground;} /** * Set whether to display as background map * * @param forbackground * default to False */public void Setforbackground (Boolean forbackground) {th Is.forbackground = Forbackground;} /** * Canceled * * @return the canceled */public boolean isCanceled () {return canceled;} /** * Cancel Current task * * @param canceled * The Canceled to set */public void Setcanceled (Boolean canceled) {this.canceled = canceled;} /** * ImageView * * @return the ImageView */public imageView Getimageview () {return imageView;}  /** * @param ImageView * The ImageView to set */public void Setimageview (ImageView imageView) {This.imageview = ImageView;} /** * Desturl * * @return the Desturl */public String Getdesturl () {return desturl;} /** * @param desturl * The desturl to set */public void Setdesturl (String desturl) {this.desturl = Desturl;} /** * Handler * * @return the handler */public Asynchandler GetHandler () {return handler;} /** * @param handler * The handler to set */public void SetHandler (Asynchandler handler) {This.handler = handle R;} /** * Animation * * @return the animation */public animation getanimation () {return animation;} /** * Set the animation effect after the image download is successful * * @param animation * The animation to set */public void Setanimation (animation animatio N) {this.animation = animation;} @Overridepublic VOID run () {//Get cache address String destpath = Cachename.getcachepath (Imageview.getcontext (), desturl);//Create File Estpath); Message msg = Handler.obtainmessage ();//Determine if the file has been downloaded if (!file.exists ()) {//If not, download if (Download (Desturl, DestPath + "). T MP ")) {//create temporary cache files File temp = new file (DestPath +". tmp ");//name Temp.renameto (file) According to the download file; msg.what = Ok;msg.obj = DestPath; } else {//If the download fails, delete the temporary file Msg.what = fail;deletetemp (DestPath + ". tmp");}} else {msg.what = Exsit;msg.obj = DestPath;} if (!canceled) {handler.sendmessage (msg);} else {//If the download is interrupted, the temporary file deletetemp (DestPath + ". tmp") is cleared;}} private void Deletetemp (String path) {File File = new file (path), if (File.exists ()) {File.delete ();}} Private Boolean Download (String imageUrl, String destpath) {//delete temporary file Deletetemp (destpath) with the same name; Boolean success = false; URL url = null;inputstream is = Null;outputstream out = null; HttpURLConnection conn = null;//download picture try {url = new URL (IMAGEURL); conn = (httpurlconnection) url.openconnection (); conn.se TconnecttimeOut (20000); Conn.setreadtimeout (5 * +); Conn.setdoinput (true); Conn.setrequestproperty ("Accept-language", " ZH-CN "); Conn.setrequestproperty (" User-agent "," mozilla/4.0 "(compatible; MSIE 8.0; Windows NT 5.2; trident/4.0;. NET CLR 1.1.4322;. NET CLR 2.0.50727;. NET CLR 3.0.04506.30;. NET CLR 3.0.4506.2152;. NET CLR 3.5.30729); c Onn.setrequestproperty ("Connection", "keep-alive"); Conn.connect (); if (conn.getresponsecode () = =) {is =  Conn.getinputstream (); int read = 0;byte[] buffer = new byte[1024];//Gets the input stream of the cache path out = new FileOutputStream (destpath); (read = is.read (buffer))! =-1) {//write data out.write (buffer, 0, read);} Returns the success of the identity bit success = true;} else {log.d (TAG, "The Respond Code is--->" + conn.getresponsecode ()); LOG.D (TAG, "The URL is:" + ImageUrl);}} catch (Malformedurlexception e) {log.d (TAG, "malformedurlexception--->" + e.tostring ());} catch (IOException e) {log.d (TAG, "IOException--->" + e.tostring ());} Finally {try {if (out! = null) {Out.flush (); Out.close ();} If(conn! = null) {Conn.disconnect ();}} catch (IOException e) {log.d (TAG, e.tostring ());}} return success;} End download/** * @ClassName: Asynchandler * @author victor_freedom ([email protected]) * @createddate 2015-2-1 PM  11:16:28 * @Description: Message starter */final class Asynchandler extends Handler {@Overridepublic void handlemessage (Message msg) {switch (msg.what) {case Fail:dofail (msg); Break;default:if (forhome) {imageview.setscaletype (SCALETYPE.FIT_XY);} Dosuccess (msg); break;}} /** * @Title: Dofail * @Description: After the download fails, set the specified failed picture * @param msg * @throws */private void Dofail (Message msg) {if (Forbac Kground && Failimage! =-1) {Imageview.setbackgroundresource (failimage);} else if (!forbackground && Failimage! =-1) {Imageview.setimageresource (failimage);}} /** * @Title: dosuccess * @Description: After successful download, display * @param msg * @throws */private void dosuccess (Message msg) {//Get path Strin G Path = (String) msg.obj;//compress store Picture bitmapmanager.getinstance (). Putbitmap (path, samplesize);//Get Picture BiTMap bitmap = Bitmapmanager.getinstance (). Getbitmap (path); String tag = (string) imageview.gettag ();//Picture Set if ((null! = bitmap) && tag = = NULL | | tag.equals (TASKID)) {if (for Background) {imageview.setbackgrounddrawable (new bitmapdrawable (bitmap));} else if (!forbackground) { Imageview.setimagebitmap (bitmap);} Whether to perform an animation if (Msg.what = = OK && null! = Animation) {imageview.setanimation (animation); Animation.start ();}}} End Asynchandler}

2, Thread pool creationHere we use a custom thread pool, for an overview of the thread pool, refer to: Java Learning Notes Multi-Threading topic (ii): Thread pool Overview
/** * @ClassName: Taskqueue * @author victor_freedom ([email protected]) * @createddate 2015-2-1 pm 11:31:19 * @Descri Ption: Image Async Task Manager */public final class Taskqueue {private final static String TAG = "Taskqueue";p rivate static Taskqueue ta Skqueue = null;private static Threadpoolexecutor ThreadPool = null;//thread pool private final static int core_size = 2; Minimum number of worker threads private final static int max_size = 3; Maximum number of common threads private final static int queue_size = 20; Thread buffer queue capacity private final static long alive_time = 10; Maximum idle duration allowed by a thread private final static timeunit t_unit = Timeunit.seconds; Idle duration unit: Seconds private static blockingqueue<runnable> queue = null; Thread buffer queue private static Rejectedexecutionhandler Rejectedhandler = new Discardoldestpolicy (); Thread pool reject policy when the buffer queue is full, the task of the work queue header will be deleted//new task queue and thread pool private taskqueue () {queue = new linkedblockingqueue<runnable> ( queue_size); threadPool = new Threadpoolexecutor (core_size, max_size, Alive_time,t_unit, queue, Rejectedhandler);} /** * Single Case design * * @return taskqueue */public static Taskqueue getinstance () {if (null = = Taskqueue) {taskqueue = new Taskqueue ();} return taskqueue;} /** * Add a task * * @param task * asyncimagetask */public void AddTask (asyncimagetask Task) {//Check if local cache file already exists if ( !hadlocal (Task)) {Boolean had = false;//determines whether the task is already present in the task queue for (int i = 0; i < queue.size (); i++) {Asyncimagetask T = (as Yncimagetask) queue.element (); if (Task.gettaskid (). Equals (T.gettaskid ())) {had = true; LOG.D (TAG, "The task ID is:" + t.gettaskid ()); if (!had) {//If not present, join the execution queue if (Task.getdefaultimage ()! =-1) {if (!task.isforbackground ()) {Task.getimageview (). Setimageresource (Task.getdefaultimage ());} else {Task.getimageview (). Setbackgroundresource (Task.getdefaultimage ());}} Threadpool.execute (Task);} else {//If it already exists, no modification is made. Wait for the Execute if (task.getdefaultimage ()! =-1) {if (!task.isforbackground ()) {Task.getimageview (). Setimageresource ( Task.getdefaultimage ());} else {Task.getimageview (). Setbackgroundresource (Task.getdefaultimage ());}}}} else {//If there is a cache, take the local picture directly with the string destpath = Cachename.getcachepath (Task.getimageview (). GetContext (), Task.getdesturl ()); Message msg = new Message (); msg.what = Asyncimagetask.exsit;msg.obj = Destpath;task.gethandler (). SendMessage (msg);}}  /** * Check if cache file already exists on local * * @param task * @return existence returns TRUE, otherwise returns false */private Boolean hadlocal (Asyncimagetask Task) {String DestPath = Cachename.getcachepath (Task.getimageview (). GetContext (), Task.getdesturl ()); File File = new file (destpath), if (File.exists ()) {if (imagecheck.isavailable (DestPath)) {file.setlastmodified ( System.currenttimemillis ()); return true;} else {file.delete ();}} return false;} /** * Close all worker threads */public void ShutDown () {threadpool.shutdown (); taskqueue = Null;queue = null;}}

3, adapter writingAt Adpter, we just need to write a few lines of code.
Get the path string url = Constant.pic_base_url + news. picurl;//Create tasks Asyncimagetask task = new Asyncimagetask (HOLDER.IV, URL);//set default picture and download failed image Task.setdefaultimage ( R.drawable.news_image_default); Task.setfailimage (r.drawable.news_image_default);// Join to the task queue to execute taskqueue.getinstance (). AddTask (Task);



The above is how to use the thread pool to implement the image of the asynchronous loading process. I believe that after reading this article, we have a certain understanding of the operation of multithreading. I hope this article will help people who see this article.

Image processing for Android Development (III): Asynchronous loading of multiple images with threadpoolexcutor thread pool

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.