在网络上搜索Android图片异步加载的相关文章,目前大部分提到的解决方案,都是采用Map<String, SoftReference<Drawable>>  这样软引用的方式缓存网络图片。具体的例子见这篇文章。

核心代码如下:

 1 public class AsyncImageLoader {
 2
 3      private HashMap<String, SoftReference<Drawable>> imageCache;
 4
 5          public AsyncImageLoader() {
 6              imageCache = new HashMap<String, SoftReference<Drawable>>();
 7          }
 8
 9          public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
10              if (imageCache.containsKey(imageUrl)) {
11                  SoftReference<Drawable> softReference = imageCache.get(imageUrl);
12                  Drawable drawable = softReference.get();
13                  if (drawable != null) {
14                      return drawable;
15                  }
16              }
17              final Handler handler = new Handler() {
18                  public void handleMessage(Message message) {
19                      imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
20                  }
21              };
22              new Thread() {
23                  @Override
24                  public void run() {
25                      Drawable drawable = loadImageFromUrl(imageUrl);
26                      imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
27                      Message message = handler.obtainMessage(0, drawable);
28                      handler.sendMessage(message);
29                  }
30              }.start();
31              return null;
32          }
33
34         public static Drawable loadImageFromUrl(String url) {
35             URL m;
36             InputStream i = null;
37             try {
38                 m = new URL(url);
39                 i = (InputStream) m.getContent();
40             } catch (MalformedURLException e1) {
41                 e1.printStackTrace();
42             } catch (IOException e) {
43                 e.printStackTrace();
44             }
45             Drawable d = Drawable.createFromStream(i, "src");
46             return d;
47         }
48
49          public interface ImageCallback {
50              public void imageLoaded(Drawable imageDrawable, String imageUrl);
51          }
52
53 }

最开始时我在自己的项目中也采取这样的代码段,从界面上来说没有发现什么问题,也还算流畅。可后来某次抓包分析数据的时候,在ListView异步加载图片已经完全,我在上下滑动listview时,依旧会有网络请求发出不断加载图片,非常奇怪。从以上代码里可以看到,异步加载下来的图片全都存在了imageCache中,应该可以直接调用缓存中的图片来显示就可以了。

查找资料以后发现了其中的玄机,具体可见Android官方的这篇文章,Caching Bitmaps。里面提到用 SoftReference 或者 WeakReference做图片缓存的方法在Android 2.3版本以后已经不被推荐了。因为内存对SoftReference和WeakReference的回收更加频繁,从而也导致了我在上面说的反复从网络上拉取图片的操作。

Android官方推荐最新的解决办法,是采用LruCache。如果图片数量巨大,也可以进一步考虑将图片缓存到sd卡中,可以采用DiskLruCache。具体的逻辑和上文其实差不多。相关代码如下:

 1 private LruCache<String, Bitmap> mMemoryCache;
 2
 3 @Override
 4 protected void onCreate(Bundle savedInstanceState) {
 5     ...
 6     // Get max available VM memory, exceeding this amount will throw an
 7     // OutOfMemory exception. Stored in kilobytes as LruCache takes an
 8     // int in its constructor.
 9     final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
10
11     // Use 1/8th of the available memory for this memory cache.
12     final int cacheSize = maxMemory / 8;
13
14     mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
15         @Override
16         protected int sizeOf(String key, Bitmap bitmap) {
17             // The cache size will be measured in kilobytes rather than
18             // number of items.
19             return bitmap.getByteCount() / 1024;
20         }
21     };
22     ...
23 }
24
25 public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
26     if (getBitmapFromMemCache(key) == null) {
27         mMemoryCache.put(key, bitmap);
28     }
29 }
30
31 public Bitmap getBitmapFromMemCache(String key) {
32     return mMemoryCache.get(key);
33 }

转载于:https://www.cnblogs.com/berylqliu/p/6261524.html

Android 图片异步加载的体会,SoftReference已经不再适用相关推荐

  1. Android 图片异步加载

    所谓图片异步加载,意思是不用一次把图片全部加载完,你可以叫它延迟加载,缓冲加载都行. 看看你有没有这种需求:某篇文章图片很多,如果在载入文章时就载入所有图片,无疑会延缓载入速度,让用户等更久,所以,我 ...

  2. android图片异步加载图片,Android 异步加载图片分析总结

    研究了android从网络上异步加载图像,现总结如下: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new ...

  3. android图片异步加载解决步骤

    Android – Asynchronous image loading in ListView Problem: How to load images in ListView asynchronou ...

  4. 又优化了一下 Android ListView 异步加载图片

    写这篇文章并不是教大家怎么样用listview异步加载图片,因为这样的文章在网上已经有很多了,比如这位仁兄写的就很好: http://www.iteye.com/topic/685986 我也是因为看 ...

  5. android listview 异步加载图片并防止错位

    网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...

  6. android复位机器人图片_Universal-Image-Loader 图片异步加载类库还不熟?

    码个蛋(codeegg) 第 824 次推文 作者:欢醉 博客:https://cloud.tencent.com/developer/article/1026386 码妞看世界 写在前面 这个图片异 ...

  7. android 实现异步加载图片,Android中ImageView异步加载图片类

    本源码是从网络找到经修改以方便直接调用感觉用着还可以 首先在项目中添加一个专门加载图片的类AsyncImageLoaderpackage com.demo.core; import java.io.I ...

  8. android webview 图片异步加载,Webview 图片异步加载及bug解决

    在项目中新闻显示需要使用图片的异步加载,并且在加载图片前和加载图片失败时显示默认图片. 关于webview中图片的异步加载的思路如下: 方案一:由前端同学全权负责(使用js实现异步加载) 方案二:an ...

  9. Android网络图片异步加载

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

最新文章

  1. WRF,WPS,WRF-Chem安装及编译步骤及bug总结(2)
  2. flower.php,flower.php
  3. 技巧:在 C/C++中如何构造通用的对象链表
  4. LinkedList专题3
  5. java异常代码分析
  6. 信息学奥赛一本通 1051:分段函数 | OpenJudge NOI 1.4 13
  7. 推行CMMI能在哪些方面为软件企业带来好处?
  8. Nginx测试实验--rest服务端负载均衡应用
  9. 数据库实验5 数据库的嵌套查询实验
  10. 程序名称:ROS强开首页(类似电信ADSL强开指定首页)
  11. 打开客户端出现 sorry this application cannot run under a virtual machine错误
  12. 深度学习:摩尔纹识别(翻拍检测)
  13. NR/5G - 一种TDD+FDD场景下Type I codebook size分析
  14. ssm启动不报错_ssm整合 启动表现层报错。。。
  15. 队的顺序存储和链式存储
  16. rufus制作u盘启动
  17. [转]家庭上网安装与设置教程
  18. WPS画报的电脑壁纸怎么下载
  19. [转载备用]微信直播的优势及微信直播搭建过程(点赞:主播妹子有点靓哦)
  20. Scipy sparse中关于CSC矩阵的自我理解

热门文章

  1. 卷积,特征图,转置卷积和空洞卷积的计算细节
  2. 优雅的在终端中编写Python
  3. 归档-软考网规-存储部分-san-nas-das
  4. boa服务器 系统设置,Ubuntu中配置boa服务器
  5. 程序员接私活平台_程序员去哪儿接私活?我系统总结了15个国内平台,绝对靠谱...
  6. 关于Markdown编辑器怎么写“|”等特殊符号的问题
  7. @EqualsAndHashCode
  8. slz-linux虚拟机的安装-VMware
  9. 去哪儿网2017春招在线笔试
  10. NPOI 操作EXCEL 小计