免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2633 | 回复: 1
打印 上一主题 下一主题

android listview 滚动时异步加载图片的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-05 15:56 |只看该作者 |倒序浏览
android listview 滚动时异步加载图片的问题













LoadImage.java

Java代码
  1. package com.gowin.cach;   
  2.   
  3. import java.util.Collection;   
  4. import java.util.HashMap;   
  5. import java.util.Map;   
  6. import java.util.concurrent.Callable;   
  7. import java.util.concurrent.ExecutorService;   
  8. import java.util.concurrent.Executors;   
  9. import android.graphics.Bitmap;   
  10. import android.os.Handler;   
  11. import android.os.Message;   
  12. import android.widget.ImageView;   
  13.   
  14. public class LoadImage {   
  15.     private ExecutorService executorService; // 固定五个线程来   
  16.     private ImageMemoryCache memoryCache;// 内存缓存   
  17.     private ImageFileCache fileCache;// 文件缓存   
  18.     private Map<String, ImageView> taskMap;// 存放任务   
  19.   
  20.     public LoadImage() {   
  21.         executorService = Executors.newFixedThreadPool(10);   
  22.   
  23.         memoryCache = new ImageMemoryCache();   
  24.         fileCache = new ImageFileCache();   
  25.         taskMap = new HashMap<String, ImageView>();   
  26.     }   
  27.   
  28.     public void addTask(String url, ImageView img) {   
  29.         Bitmap bitmap=memoryCache.getBitmapFromCache(url);   
  30.         if(bitmap!=null)   
  31.         {   
  32.             img.setImageBitmap(bitmap);   
  33.         }else  
  34.         {   
  35.         synchronized (taskMap) {   
  36.         taskMap.put(Integer.toString(img.hashCode()), img);   
  37.         }   
  38.         }   
  39.     }   
  40.   
  41.     public void doTask() {   
  42.         synchronized (taskMap) {   
  43.             Collection<ImageView> con = taskMap.values();   
  44.             for (ImageView i : con) {   
  45.                 if (i != null) {   
  46.                     if (i.getTag() != null) {   
  47.                         loadImage((String) i.getTag(), i);   
  48.                     }   
  49.                 }   
  50.             }   
  51.             taskMap.clear();   
  52.         }   
  53.     }   
  54.   
  55.     private void loadImage(String url, ImageView img) {   
  56.         /*** 加入新的任务 ***/  
  57.         executorService.submit(new TaskWithResult(new TaskHandler(url, img),   
  58.                 url));   
  59.     }   
  60.   
  61.     /*** 获得一个图片,从三个地方获取,首先是内存缓存,然后是文件缓存,最后从网络获取 ***/  
  62.     private Bitmap getBitmap(String url) {   
  63.         // 从内存缓存中获取图片   
  64.         Bitmap result;   
  65.         result = memoryCache.getBitmapFromCache(url);   
  66.         if (result == null) {   
  67.             // 文件缓存中获取   
  68.             result = fileCache.getImage(url);   
  69.             if (result == null) {   
  70.                 // 从网络获取   
  71.                 result = ImageGetForHttp.downloadBitmap(url);   
  72.                 if (result != null) {   
  73.                     memoryCache.addBitmapToCache(url, result);   
  74.                     fileCache.saveBmpToSd(result, url);                       
  75.                 }   
  76.             } else {   
  77.                 // 添加到内存缓存   
  78.                 memoryCache.addBitmapToCache(url, result);   
  79.             }   
  80.         }   
  81.         return result;   
  82.     }   
  83.   
  84.     /*** 完成消息 ***/  
  85.     private class TaskHandler extends Handler {   
  86.         String url;   
  87.         ImageView img;   
  88.   
  89.         public TaskHandler(String url, ImageView img) {   
  90.             this.url = url;   
  91.             this.img = img;   
  92.         }   
  93.   
  94.         @Override  
  95.         public void handleMessage(Message msg) {   
  96.             /*** 查看imageview需要显示的图片是否被改变 ***/  
  97.             if (img.getTag().equals(url)) {   
  98.                 if (msg.obj != null) {   
  99.                     Bitmap bitmap = (Bitmap) msg.obj;   
  100.                     img.setImageBitmap(bitmap);   
  101.                 }   
  102.             }   
  103.         }   
  104.     }   
  105.   
  106.     /*** 子线程任务 ***/  
  107.     private class TaskWithResult implements Callable<String> {   
  108.         private String url;   
  109.         private Handler handler;   
  110.   
  111.         public TaskWithResult(Handler handler, String url) {   
  112.             this.url = url;   
  113.             this.handler = handler;   
  114.         }   
  115.   
  116.         @Override  
  117.         public String call() throws Exception {   
  118.             Message msg = new Message();   
  119.             msg.obj = getBitmap(url);   
  120.             if (msg.obj != null) {   
  121.                 handler.sendMessage(msg);   
  122.             }   
  123.             return url;   
  124.         }   
  125.   
  126.     }   
  127. }  

  128. package com.gowin.cach;

  129. import java.util.Collection;
  130. import java.util.HashMap;
  131. import java.util.Map;
  132. import java.util.concurrent.Callable;
  133. import java.util.concurrent.ExecutorService;
  134. import java.util.concurrent.Executors;
  135. import android.graphics.Bitmap;
  136. import android.os.Handler;
  137. import android.os.Message;
  138. import android.widget.ImageView;

  139. public class LoadImage {
  140.     private ExecutorService executorService; // 固定五个线程来
  141.     private ImageMemoryCache memoryCache;// 内存缓存
  142.     private ImageFileCache fileCache;// 文件缓存
  143.     private Map<String, ImageView> taskMap;// 存放任务

  144.     public LoadImage() {
  145.         executorService = Executors.newFixedThreadPool(10);

  146.         memoryCache = new ImageMemoryCache();
  147.         fileCache = new ImageFileCache();
  148.         taskMap = new HashMap<String, ImageView>();
  149.     }

  150.     public void addTask(String url, ImageView img) {
  151.         Bitmap bitmap=memoryCache.getBitmapFromCache(url);
  152.         if(bitmap!=null)
  153.         {
  154.             img.setImageBitmap(bitmap);
  155.         }else
  156.         {
  157.         synchronized (taskMap) {
  158.         taskMap.put(Integer.toString(img.hashCode()), img);
  159.         }
  160.         }
  161.     }

  162.     public void doTask() {
  163.         synchronized (taskMap) {
  164.             Collection<ImageView> con = taskMap.values();
  165.             for (ImageView i : con) {
  166.                 if (i != null) {
  167.                     if (i.getTag() != null) {
  168.                         loadImage((String) i.getTag(), i);
  169.                     }
  170.                 }
  171.             }
  172.             taskMap.clear();
  173.         }
  174.     }

  175.     private void loadImage(String url, ImageView img) {
  176.         /*** 加入新的任务 ***/
  177.         executorService.submit(new TaskWithResult(new TaskHandler(url, img),
  178.                 url));
  179.     }

  180.     /*** 获得一个图片,从三个地方获取,首先是内存缓存,然后是文件缓存,最后从网络获取 ***/
  181.     private Bitmap getBitmap(String url) {
  182.         // 从内存缓存中获取图片
  183.         Bitmap result;
  184.         result = memoryCache.getBitmapFromCache(url);
  185.         if (result == null) {
  186.             // 文件缓存中获取
  187.             result = fileCache.getImage(url);
  188.             if (result == null) {
  189.                 // 从网络获取
  190.                 result = ImageGetForHttp.downloadBitmap(url);
  191.                 if (result != null) {
  192.                     memoryCache.addBitmapToCache(url, result);
  193.                     fileCache.saveBmpToSd(result, url);                    
  194.                 }
  195.             } else {
  196.                 // 添加到内存缓存
  197.                 memoryCache.addBitmapToCache(url, result);
  198.             }
  199.         }
  200.         return result;
  201.     }

  202.     /*** 完成消息 ***/
  203.     private class TaskHandler extends Handler {
  204.         String url;
  205.         ImageView img;

  206.         public TaskHandler(String url, ImageView img) {
  207.             this.url = url;
  208.             this.img = img;
  209.         }

  210.         @Override
  211.         public void handleMessage(Message msg) {
  212.             /*** 查看imageview需要显示的图片是否被改变 ***/
  213.             if (img.getTag().equals(url)) {
  214.                 if (msg.obj != null) {
  215.                     Bitmap bitmap = (Bitmap) msg.obj;
  216.                     img.setImageBitmap(bitmap);
  217.                 }
  218.             }
  219.         }
  220.     }

  221.     /*** 子线程任务 ***/
  222.     private class TaskWithResult implements Callable<String> {
  223.         private String url;
  224.         private Handler handler;

  225.         public TaskWithResult(Handler handler, String url) {
  226.             this.url = url;
  227.             this.handler = handler;
  228.         }

  229.         @Override
  230.         public String call() throws Exception {
  231.             Message msg = new Message();
  232.             msg.obj = getBitmap(url);
  233.             if (msg.obj != null) {
  234.                 handler.sendMessage(msg);
  235.             }
  236.             return url;
  237.         }

  238.     }
  239. }  
复制代码
ImageMemoryCache.java  (http://www.my400800.cn )


Java代码
  1. package com.gowin.cach;   
  2.   
  3. import java.lang.ref.SoftReference;   
  4. import java.util.HashMap;   
  5. import java.util.LinkedHashMap;   
  6. import java.util.concurrent.ConcurrentHashMap;   
  7.   
  8. import android.graphics.Bitmap;   
  9. /****  
  10. *内存中的缓存   
  11. ****/  
  12. public class ImageMemoryCache {   
  13.       private static final int HARD_CACHE_CAPACITY = 30;   
  14.       private HashMap<String, Bitmap> mHardBitmapCache ;   
  15.       private final static ConcurrentHashMap<String, SoftReference<Bitmap>> mSoftBitmapCache =   
  16.             new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);   
  17.                  
  18.       public ImageMemoryCache()         
  19.       {   
  20.           mHardBitmapCache =   
  21.                 new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {   
  22.                 /**  
  23.                      *   
  24.                      */  
  25.                     private static final long serialVersionUID = 1L;   
  26.   
  27.                 @Override  
  28.                 protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {   
  29.                     if (size() > HARD_CACHE_CAPACITY) {   
  30.                         // Entries push-out of hard reference cache are transferred to soft reference cache   
  31.                         mSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));   
  32.                         return true;   
  33.                     } else  
  34.                         return false;   
  35.                 }   
  36.             };   
  37.   
  38.       }   
  39.          
  40.       /**  
  41.       * 从缓存中获取图片  
  42.       */  
  43.       public Bitmap getBitmapFromCache(String url) {   
  44.       // 先从mHardBitmapCache缓存中获取   
  45.       synchronized (mHardBitmapCache) {   
  46.       final Bitmap bitmap =mHardBitmapCache.get(url);   
  47.       if (bitmap != null) {   
  48.       //如果找到的话,把元素移到linkedhashmap的最前面,从而保证在LRU算法中是最后被删除   
  49.       mHardBitmapCache.remove(url);   
  50.       mHardBitmapCache.put(url,bitmap);   
  51.       return bitmap;   
  52.       }   
  53.       }   
  54.       //如果mHardBitmapCache中找不到,到mSoftBitmapCache中找   
  55.       SoftReference<Bitmap>bitmapReference = mSoftBitmapCache.get(url);   
  56.       if (bitmapReference != null) {   
  57.       final Bitmap bitmap =bitmapReference.get();   
  58.       if (bitmap != null) {   
  59.           //将图片移回硬缓存   
  60.           mHardBitmapCache.put(url, bitmap);   
  61.           mSoftBitmapCache.remove(url);   
  62.       return bitmap;   
  63.       } else {   
  64.       mSoftBitmapCache.remove(url);   
  65.       }   
  66.       }   
  67.       return null;   
  68.       }   
  69.       /***添加图片到缓存***/  
  70.       public void addBitmapToCache(String url, Bitmap bitmap) {   
  71.             if (bitmap != null) {   
  72.                 synchronized (mHardBitmapCache) {   
  73.                     mHardBitmapCache.put(url, bitmap);   
  74.                 }   
  75.             }   
  76.         }   
  77. }  

  78. package com.gowin.cach;

  79. import java.lang.ref.SoftReference;
  80. import java.util.HashMap;
  81. import java.util.LinkedHashMap;
  82. import java.util.concurrent.ConcurrentHashMap;

  83. import android.graphics.Bitmap;
  84. /****
  85. *内存中的缓存
  86. ****/
  87. public class ImageMemoryCache {
  88.       private static final int HARD_CACHE_CAPACITY = 30;
  89.       private HashMap<String, Bitmap> mHardBitmapCache ;
  90.       private final static ConcurrentHashMap<String, SoftReference<Bitmap>> mSoftBitmapCache =
  91.             new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);
  92.               
  93.       public ImageMemoryCache()      
  94.       {
  95.           mHardBitmapCache =
  96.                 new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {
  97.                 /**
  98.                      *
  99.                      */
  100.                     private static final long serialVersionUID = 1L;

  101.                 @Override
  102.                 protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
  103.                     if (size() > HARD_CACHE_CAPACITY) {
  104.                         // Entries push-out of hard reference cache are transferred to soft reference cache
  105.                         mSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));
  106.                         return true;
  107.                     } else
  108.                         return false;
  109.                 }
  110.             };

  111.       }
  112.       
  113.       /**
  114.       * 从缓存中获取图片
  115.       */
  116.       public Bitmap getBitmapFromCache(String url) {
  117.       // 先从mHardBitmapCache缓存中获取
  118.       synchronized (mHardBitmapCache) {
  119.       final Bitmap bitmap =mHardBitmapCache.get(url);
  120.       if (bitmap != null) {
  121.       //如果找到的话,把元素移到linkedhashmap的最前面,从而保证在LRU算法中是最后被删除
  122.       mHardBitmapCache.remove(url);
  123.       mHardBitmapCache.put(url,bitmap);
  124.       return bitmap;
  125.       }
  126.       }
  127.       //如果mHardBitmapCache中找不到,到mSoftBitmapCache中找
  128.       SoftReference<Bitmap>bitmapReference = mSoftBitmapCache.get(url);
  129.       if (bitmapReference != null) {
  130.       final Bitmap bitmap =bitmapReference.get();
  131.       if (bitmap != null) {
  132.           //将图片移回硬缓存
  133.           mHardBitmapCache.put(url, bitmap);
  134.           mSoftBitmapCache.remove(url);
  135.       return bitmap;
  136.       } else {
  137.       mSoftBitmapCache.remove(url);
  138.       }
  139.       }
  140.       return null;
  141.       }
  142.       /***添加图片到缓存***/
  143.       public void addBitmapToCache(String url, Bitmap bitmap) {
  144.             if (bitmap != null) {
  145.                 synchronized (mHardBitmapCache) {
  146.                     mHardBitmapCache.put(url, bitmap);
  147.                 }
  148.             }
  149.         }
  150. }  
复制代码
ImageFileCache.java

论坛徽章:
0
2 [报告]
发表于 2011-12-23 23:16 |只看该作者
谢谢分享  希望于楼主多多交流
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP