05_Smart-image通过SoftReference提高性能
文章导读:
文件介绍了常见的图片下载开源插件smart-image, 由于移动设备硬件受限,因此Android的相关app都要考虑到性能的关系, 所以很多的第三方插件都使用到了缓存cache技术,本人就是从源码的角度来解析它们的实现机制. 它属于github中的开源项目, 开源直接在github中搜索下载即可.
视频与源码下载:http://edu.51cto.com/lecturer/index/user_id-9166337.html (代码在视频的附件中)
Android的smart-image图片显示插件为了提高性能使用了一、二级缓存, 其中一级缓存也就是内存级缓存采用的就是SoftReference,本章我们来分析下它的源码实现. 由于源码分析本身比较复杂,类与类之间调用关系比较复杂.建议有时间的同学还是看视频.文章最后附上一张完成的源码调用关系图. 在分析之前我们先看下结果.
首先我们说明下几个类之间的关系, 下面仅仅列出来了核心代码, 详细关系可以查看文件底部的关系图, 或者视频教程
- SmartImageView 继承了ImageView 主要是对父类进行了功能增强,用来显示下载的图片
- WebImage 里面的getBitmapFromUrl(String url) 方法主要是来完成文件下载的功能.但是在下载之前需要在一二级缓存进行判断.如果没有才到网络下载
- WebImageCache 用名称也可以看出来,一二级缓存的实现类,其中一级缓存采用的就是SoftReference,二级缓存是硬盘级缓存
WebImage 中读取缓存的代码如下:
1 public class WebImage implements SmartImage { 2 public Bitmap getBitmap(Context context) { 3 // 如果没有缓存对象,则先创建缓存对象 4 if(webImageCache == null) { 5 webImageCache = new WebImageCache(context); 6 } 7 8 // 判断是否有缓存,如果没有缓存则从网络下载,并存储到缓存中 9 Bitmap bitmap = null; 10 if(url != null) { 11 bitmap = webImageCache.get(url); 12 if(bitmap == null) { 13 bitmap = getBitmapFromUrl(url); 14 if(bitmap != null){ 15 webImageCache.put(url, bitmap); 16 } 17 } 18 } 19 20 return bitmap; 21 } 22 }
如果缓存中没有数据, WebImage通过Http请求下载网络图片:
1 private Bitmap getBitmapFromUrl(String url) { 2 Bitmap bitmap = null; 4 try { 5 URLConnection conn = new URL(url).openConnection(); 6 conn.setConnectTimeout(CONNECT_TIMEOUT); 7 conn.setReadTimeout(READ_TIMEOUT); 8 bitmap = BitmapFactory.decodeStream((InputStream) conn.getContent()); 9 } catch(Exception e) { 10 e.printStackTrace(); 11 } 12 13 return bitmap; 14 }
WebImageCache用来存储缓存目录的基本配置:
1 public class WebImageCache { 2 private static final String DISK_CACHE_PATH = "/web_image_cache/"; 3 // 用来存储一级缓存的软引用 4 private ConcurrentHashMap<String, SoftReference<Bitmap>> memoryCache; 5 private String diskCachePath; 6 private boolean diskCacheEnabled = false; 7 private ExecutorService writeThread; 8 }
WebImageCache中通过URL地址在缓存中查找的代码, 选从一级缓存中查找, 如果查找失败则从二级缓存中查找.
1 public Bitmap get(final String url) { 2 Bitmap bitmap = null; 3 4 // Check for image in memory 5 bitmap = getBitmapFromMemory(url); 6 7 // Check for image on disk cache 8 if(bitmap == null) { 9 bitmap = getBitmapFromDisk(url); 10 11 // Write bitmap back into memory cache 12 if(bitmap != null) { 13 cacheBitmapToMemory(url, bitmap); 14 } 15 } 16 17 return bitmap; 18 }
三个类与类之间的关系图如下(图片另存为到本地可以放大观看)