The method of realizing the asynchronous loading of network picture in the application of Android _java

Source: Internet
Author: User

Objective
in fact, very lucky, after a week to follow two brothers to do Android development, Senior are great God, as a small white I can only learn a lot, a lot of effort. Recently have been busy not a chance to summarize, today just finished the Android client picture asynchronous loading class, here record (PS: Actually I am here is the reference online open source implementation)


principle
the principle of loading pictures in ListView or GridView is basically the same:

Get it from the memory cache first, fetch it back, take the next step
Gets from the file cache, takes it back and updates it to the memory cache, takes the next step
Downloading pictures from the network and updating the memory cache and file cache


The flowchart is as follows:

Also, be aware of the number of threads. Generally loading pictures in ListView, everyone is to open a new thread to load, but when fast sliding, it is easy to cause oom, so need to control the number of threads. We can control the number of threads through the thread pool, and the size of the thread pool needs to be judged by the processor and the business.

The thread pool is established by the following methods:

Executorservice Executorservice = Executors.newfixedthreadpool (5); 5 is variable. 

File Cache class

 Import Java.io.File; 
   
  Import Android.content.Context; 
    public class Filecache {private static final String Dir_name = "Your_dir"; 
   
    Private File Cachedir; Public Filecache {//Find the directory to save cached images if (ANDROID.OS.ENVIRONMENT.G 
            Etexternalstoragestate (). Equals (Android.os.Environment.MEDIA_MOUNTED)) {Cachedir = new File ( 
      Android.os.Environment.getExternalStorageDirectory (), dir_name); 
      else {cachedir = Context.getcachedir (); 
      } if (!cachedir.exists ()) {cachedir.mkdirs (); } public File getFile (String URL) {//Identify images by URL ' s hash code String filename = 
   
      String.valueof (Url.hashcode ()); 
   
      File F = new file (cachedir, filename); 
    return F; 
      public void Clear () {file[] files = cachedir.listfiles (); if (files = null) {REturn; 
        else {for (File f:files) {f.delete (); 
 } 
      } 
    } 
  }

Memory Cache Class
here using a soft reference, map<string, softreference<bitmap>> cache, you can Google a soft reference mechanism, simply said: the implementation of the MAP, while the memory is tight can be recycled, does not cause memory leaks

 Import java.lang.ref.SoftReference; 
  Import java.util.Collections; 
  Import Java.util.LinkedHashMap; 
  Import Java.util.Map; 
   
  Import Android.graphics.Bitmap; 
   
  public class MemoryCache { 
    private map<string, softreference<bitmap>> cache = Collections 
        . Synchronizedmap (New linkedhashmap<string, softreference<bitmap>> ( 
            1.5f, True)); 
   
    Public Bitmap get (String ID) { 
      if (!cache.containskey (ID)) {return 
        null; 
      } 
   
      Softreference<bitmap> ref = Cache.get (ID); 
   
      return Ref.get (); 
    } 
   
    public void put (String ID, Bitmap Bitmap) { 
      cache.put (ID, new softreference<bitmap> (Bitmap)); 
   
    public void Clear () { 
      cache.clear (); 
    } 
  } 

Picture Load Class

  Import Java.io.File; 
  Import Java.io.FileInputStream; 
  Import java.io.FileNotFoundException; 
  Import Java.io.FileOutputStream; 
  Import Java.io.InputStream; 
  Import Java.io.OutputStream; 
  Import java.net.HttpURLConnection; 
  Import Java.net.URL; 
  Import java.util.Collections; 
  Import Java.util.Map; 
  Import Java.util.WeakHashMap; 
  Import Java.util.concurrent.ExecutorService; 
   
  Import java.util.concurrent.Executors; 
  Import Android.content.Context; 
  Import Android.graphics.Bitmap; 
  Import Android.graphics.BitmapFactory; 
  Import Android.os.Handler; 
   
  Import Android.widget.ImageView; 
    public class Imageloader {/** * Network time Out */private static final int time_out = 30000; 
   
    /** * Default Picture Resource * * private static final int default_bg = R.DRAWABLE.PLATE_LIST_HEAD_BG; 
   
    /** * Thread Pool number */private static final int thread_num = 5; /** * Memory imaGE Cache */memorycache memorycache = new MemoryCache (); 
   
    /** * File Image Cache */Filecache filecache; 
        /** * Judge Image View If it is reuse * * Private map<imageview, string> imageviews = Collections 
   
    . Synchronizedmap (New Weakhashmap<imageview, string> ()); 
   
    /** * Thread Pool * * Executorservice executorservice; 
   
    /** * Handler to display images in UI thread * * Handler Handler = new Handler (); 
      Public Imageloader {filecache = new Filecache (context); 
    Executorservice = Executors.newfixedthreadpool (thread_num); 
      public void displayimage (String url, ImageView imageview) {imageviews.put (ImageView, URL); 
      Bitmap Bitmap = memorycache.get (URL); 
      if (bitmap!= null) {//Display image from Memory cache Imageview.setimagebitmap (bitmap); else {//Display imaGE from File cache or network Queuephoto (URL, imageview); }} private void Queuephoto (String url, ImageView imageview) {phototoload phototoload = new Phototol 
      Oad (URL, imageview); 
    Executorservice.submit (New Photosloader (phototoload)); 
   
      Private Bitmap getbitmap (String URL) {File f = filecache.getfile (URL); 
      From File cache Bitmap BMP = DecodeFile (f); 
      if (BMP!= null) {return BMP; 
        }//From network try {Bitmap Bitmap = null; 
        URL imageUrl = new URL (URL); 
        HttpURLConnection conn = (httpurlconnection) imageUrl. OpenConnection (); 
        Conn.setconnecttimeout (time_out); 
        Conn.setreadtimeout (time_out); 
        Conn.setinstancefollowredirects (TRUE); 
        InputStream is = Conn.getinputstream (); 
        OutputStream OS = new FileOutputStream (f); 
        CopyStream (is, OS); 
        Os.close (); Conn.discoNnect (); 
        Bitmap = DecodeFile (f); 
      return bitmap; 
        The catch (Throwable ex) {if (ex instanceof OutOfMemoryError) {clearcache (); 
      return null; 
   
      } private void CopyStream (InputStream is, OutputStream os) {int buffer_size = 1024; 
        try {byte[] bytes = new Byte[buffer_size]; 
          while (true) {int count = is.read (bytes, 0, buffer_size); 
          if (count = = 1) {break; 
        } os.write (Bytes, 0, count); 
        (Exception e) {}} private Bitmap DecodeFile (File f) {try { 
        todo:compress image size FileInputStream FileInputStream = new FileInputStream (f); 
        Bitmap Bitmap = Bitmapfactory.decodestream (FileInputStream); 
   
      return bitmap; 
      catch (FileNotFoundException e) {return null; }} private void clearCache () {memorycache.clear (); 
    Filecache.clear (); /** * Task for the queue * * * @author zhengyi.wzy * */Private class Phototol 
      oad {public String URL; 
   
      Public ImageView ImageView; 
        Public phototoload (String URL, ImageView imageview) {this.url = URL; 
      This.imageview = ImageView;  }/** * Asynchronous to load Picture * * @author Zhengyi.wzy */class 
   
      Photosloader implements Runnable {Phototoload phototoload; 
      Public Photosloader (Phototoload phototoload) {this.phototoload = Phototoload; Private Boolean imageviewreused (Phototoload phototoload) {String tag = Imageviews.get (phototoload.i 
        Mageview); 
        if (tag = = NULL | |!tag.equals (PHOTOTOLOAD.URL)) {return true; 
      return false; @Override public void Run () {
        Abort Current thread If Image View reused if (imageviewreused (phototoload)) {return; 
   
        } Bitmap Bitmap = Getbitmap (Phototoload.url); 
   
        Update Memory memorycache.put (Phototoload.url, bitmap); 
        if (imageviewreused (phototoload)) {return; }//Don ' t change UI in children thread bitmapdisplayer BD = new Bitmapdisplayer (Bitmap, Phototoload 
        ); 
      Handler.post (BD); 
        Class Bitmapdisplayer implements Runnable {Bitmap Bitmap; 
   
        Phototoload Phototoload; 
          Public Bitmapdisplayer (Bitmap Bitmap, Phototoload phototoload) {this.bitmap = Bitmap; 
        This.phototoload = Phototoload; 
          @Override public void Run () {if (imageviewreused (phototoload)) {return; } if (bitmap!= null) {PHOTOTOLOAD.IMAGEVIEW.SETIMAGEBITMAP (bitmap); 
          else {photoToLoad.imageView.setImageResource (DEFAULT_BG); 

 } 
        } 
   
      } 
    } 
  }

Call method

  Imageloader Imageloader = new Imageloader (context); 
  Imageloader.displayimage (IMAGEURL, ImageView); 


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.