在Android的应用中实现网络图片异步加载的方法

在Android的应用中实现网络图片异步加载的方法,第1张

概述前言其实很幸运,入职一周之后就能跟着两个师兄做android开发,师兄都是大神,身为小白的我只能多多学习,多多努力。最近一段时间都忙的没机会总结,今天刚完成了android客户端图片异步加载的类,这里记录一下(ps:

前言
其实很幸运,入职一周之后就能跟着两个师兄做androID开发,师兄都是大神,身为小白的我只能多多学习,多多努力。最近一段时间都忙的没机会总结,今天刚完成了androID客户端图片异步加载的类,这里记录一下(ps:其实我这里都是参考网上开源实现)


原理
在ListVIEw或者GrIDVIEw中加载图片的原理基本都是一样的:

    先从内存缓存中获取,取到则返回,取不到进行下一步
    从文件缓存中获取,取到则返回并更新到内存缓存,取不到则进行进行下一步
    从网络上下载图片,并更新内存缓存和文件缓存


流程图如下:

同时,要注意线程的数量。一般在ListvIEw中加载图片,大家都是开启新的线程去加载,但是当快速滑动时,很容易造成OOM,因此需要控制线程数量。我们可以通过线程池控制线程的数量,具体线程池的大小还需要根据处理器的情况和业务情况自行判断

建立线程池的方法如下:

   

ExecutorService executorService = Executors.newFixedThreadPool(5); // 5是可变的 

文件缓存类

   

 import java.io.file;      import androID.content.Context;      public class fileCache {     private static final String DIR_name = "your_dir";     private file cacheDir;        public fileCache(Context context) {       // Find the directory to save cached images       if (androID.os.Environment.getExternalStorageState().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();         }       }     }   } 

内存缓存类
这里使用了软引用,Map<String,SoftReference<Bitmap>> cache,可以Google一下软引用的机制,简单的说:实现了map,同时当内存紧张时可以被回收,不会造成内存泄露

   

 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>>(             10,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();     }   } 

图片加载类

  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(Context context) {       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 PhotoToload(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;       } 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,buffer_size);           if (count == -1) {             break;           }           os.write(bytes,count);         }          } catch (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 PhotoToload {       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.imageVIEw);         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);           }         }          }     }   } 

调用方法

  ImageLoader imageLoader = new ImageLoader(context);   imageLoader.disPlayImage(imageUrl,imageVIEw); 

总结

以上是内存溢出为你收集整理的在Android的应用中实现网络图片异步加载的方法全部内容,希望文章能够帮你解决在Android的应用中实现网络图片异步加载的方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1142299.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存