Milo has not updated his blog for some time since he started blogging. The main thing is that Milo was too busy for the project to develop this time. Today Saturday is still working overtime in the company.
Today in the project, there is a implementation of the asynchronous loading of the image function, although relatively simple, but still record it. Because Milo previously implemented the asynchronous loading of images using the Asyntask API, continuing this class is very simple and convenient to implement. In Doinbackground () method to implement the download logic. The specific implementation is as follows
The implementation logic is: read from memory first, if there is this picture in memory, then use directly, if the memory is not read to SDcard, if there is a display; If the sdcard is not yet read on the network. In-memory open cache is a reference to the implementation of the Web. Milo is here to thank for the program apes who like to share.
public class Imagedownloader extends Asynctask<string, Integer, object> {private static final String TAG = "Imag Edownloader "; To speed up, the cache is turned on in memory (mainly for repeated pictures, or the same image is accessed multiple times, such as scrolling back and forth in the ListView) private map<string, softreference<drawable >> Imagecache = new hashmap<string, softreference<drawable>> (); /** * Controls for displaying pictures */private ImageView Mimageview; Public Imagedownloader (ImageView image) {Mimageview = image; } @Override protected void OnPreExecute () {super.onpreexecute (); } @Override protected Object doinbackground (String ... params) {//LOG.I ("Imagedownloader", "Loading image". ."); String URL = params[0]; Drawable drawable = null; try {if (! "). Equals (URL) && URL! = null) {String fileName = Url.hashcode () + ". jpg"; If the cache has been cached, remove the data from the cache if (Imagecache.containskey (FileName)) {Softreference<drawable> softreference = Imagecache.get (fileName); drawable = Softreference.get (); if (drawable! = null) {return drawable; }} File Dir = new file (Fileconstant.image_file_path); if (!dir.exists ()) {Boolean m = Dir.mkdirs (); } File File = New file (dir, fileName); if (file.exists () && file.length () > 0) {log.i (TAG, "Load image from SD card"); If the file exists, read directly sdcard drawable = Readfromsdcard (file); } else {//file.createnewfile (); LOG.I (TAG, "Load image from Network"); URL imageUrl = new URL (URL); Write SDcard if (Environment.getexternalstoragestate (). Equals (environment.media_mounted)) { Saveimagefile (ImageuRL, file); drawable = Drawable.createfromstream (new FileInputStream (file), fileName); }else{//read directly from the stream drawable = Drawable.createfromstream (Imageurl.openstream (), FileName); }} if (Drawable!=null) {//saved in cache Imagecache.put (Filena Me, New softreference<drawable> (drawable)); }}} catch (Exception e) {e.printstacktrace (); } return drawable; }/** * Save image*/private void saveimagefile (URL url, file file) {fileoutputstream out = null; InputStream in = null; try {file.deleteonexit (); out = new FileOutputStream (file); in = Url.openstream (); byte[] buf = new byte[1024]; int len =-1; while (len = In.read (buf))!=-1) {out.write (buf, 0, Len); Out.flush (); }} catch (Exception e) {e.printstacktrace (); } finally {if (out!=null) {try {out.close (); } catch (IOException e) {e.printstacktrace (); }} if (In!=null) {try {in.close (); } catch (IOException e) {e.printstacktrace (); }}}}/** * Get the picture from SDcard * * * Private drawable Readfromsdcard (file file) throws Exception { FileInputStream in = new FileInputStream (file); Return Drawable.createfromstream (In, File.getname ()); } @Override protected void OnPostExecute (Object result) {Super.onpostexecute (result); Drawable drawable = (drawable) result; if (Mimageview! = NULL && drawable! = null) {mimageview.setbackgrounddrawable (drawable); } } @Override protected void Onprogressupdate (Integer ... values) {super.onprogressupdate (values); } @Override protected void oncancelled () {super.oncancelled (); }}
When used:
Imagedownloader loader = new Imagedownloader (ImageView); Loader.execute (URL);
In fact, there are some hidden dangers, that is, the implementation of this class is still a bit of a problem. For example, every time you set up a picture on the network in the ImageView, it is not used in the memory cache of this class, that is Imagecache
map<string, softreference<drawable>> imagecache = new hashmap<string, softreference<drawable> > ();
Because each time the ImageView is set, it is a new Imagedownloader object. So each Imagedownloader object is a separate imagecache. In addition, Asyntask is also a thread. Each use of the thread load picture, the number of threads is not displayed, after all, the number of threads is still limited. So Milo discovered this problem today, and then referred to the realization of others, using the thread pool, the implementation of logic is the same as the code, Read from memory first, if not to sdcard read, if still not, it is network read, implementation does not use Asyntask, the specific code is as follows:
/** * Asynchronously loads the picture and sets the picture to the ImageView control */public class Imagedownloader extends Asynctask<string, Integer, object> {Priva Te static final String TAG = "Imagedownloader"; To speed up, the cache is turned on in memory (mainly for repeated pictures, or the same image is accessed multiple times, such as scrolling back and forth in the ListView) private map<string, softreference<drawable >> Imagecache = new hashmap<string, softreference<drawable>> (); /** * Controls for displaying pictures */private ImageView Mimageview; Public Imagedownloader (ImageView image) {Mimageview = image; } @Override protected void OnPreExecute () {super.onpreexecute (); } @Override protected Object doinbackground (String ... params) {//LOG.I ("Imagedownloader", "Loading image". ."); String URL = params[0]; Drawable drawable = null; try {if (! "). Equals (URL) && URL! = null) {String fileName = Url.hashcode () + ". jpg"; If the cache has been cached, remove the data from the cache if (Imagecache.containskey (FileName)) { softreference<drawable> softreference = Imagecache.get (fileName); drawable = Softreference.get (); if (drawable! = null) {return drawable; }} File Dir = new file (Fileconstant.image_file_path); if (!dir.exists ()) {Boolean m = Dir.mkdirs (); } File File = New file (dir, fileName); if (file.exists () && file.length () > 0) {log.i (TAG, "Load image from SD card"); If the file exists, read directly sdcard drawable = Readfromsdcard (file); } else {//file.createnewfile (); LOG.I (TAG, "Load image from Network"); URL imageUrl = new URL (URL); Write SDcard if (Environment.getexternalstoragestate (). Equals (environment.media_mounted)) { Saveimagefile (imageUrl, file); drawable = Drawable.createfromstream (new FileInputStream (file), fileName); }else{//read directly from the stream drawable = Drawable.createfromstream (Imageurl.openstream (), FileName); }} if (Drawable!=null) {//saved in cache Imagecache.put (Filena Me, New softreference<drawable> (drawable)); }}} catch (Exception e) {e.printstacktrace (); } return drawable; }/** * Save image*/private void saveimagefile (URL url, file file) {fileoutputstream out = null; InputStream in = null; try {file.deleteonexit (); out = new FileOutputStream (file); in = Url.openstream (); byte[] buf = new byte[1024]; int len =-1; while (len = In.read (buf))!=-1) { Out.write (buf, 0, Len); Out.flush (); }} catch (Exception e) {e.printstacktrace (); } finally {if (out!=null) {try {out.close (); } catch (IOException e) {e.printstacktrace (); }} if (In!=null) {try {in.close (); } catch (IOException e) {e.printstacktrace (); }}}}/** * get picture from SDcard * * Private drawable Readfromsdcard (file file) throws Exception {FileInputStream in = new FileInputStream (file); Return Drawable.createfromstream (In, File.getname ()); } @Override protected void OnPostExecute (Object result) {Super.onpostexecute (result); Drawable drawable = (drawable) result; if (Mimageview = null && drawable! = null) {MIMAGEVIEW.SETBACKGRounddrawable (drawable); }} @Override protected void Onprogressupdate (Integer ... values) {super.onprogressupdate (values); } @Override protected void oncancelled () {super.oncancelled (); }}
The use of this ImageDownloader2 is also very simple
public class Imageutil { /** * Image Loader */ static ImageDownloader2 loader = null; /** * Load image*/public static void LoadImage (String url,final ImageView ImageView) { if (loader = = null) { C8/>loader = new ImageDownloader2 (); } Loader.loaddrawable (URL, new Imagecallback () { @Override public void imageloaded (drawable imagedrawable) { C13/>if (imagedrawable!=null) { imageview.setbackgrounddrawable (imagedrawable);}} );} }
Each time you use a reference that calls Imageutil.loadimage (Url,imageview) to have the picture URL already required to display a picture of the control ImageView pass in.
Android for loading images asynchronously