Android开发笔记之图片缓存、手势及OOM分析

2019-12-10 19:27:12丽君

(1) 图片缓存->媒体缓存
Glide 不仅是一个图片缓存,它支持 Gif、WebP、缩略图。甚至是 Video,所以更该当做一个媒体缓存。

(2) 支持优先级处理

(3) 与 Activity/Fragment 生命周期一致,支持 trimMemory
Glide 对每个 context 都保持一个 RequestManager,通过 FragmentTransaction 保持与 Activity/Fragment 生命周期一致,并且有对应的 trimMemory 接口实现可供调用。

(4) 支持 okhttp、Volley
Glide 默认通过 UrlConnection 获取数据,可以配合 okhttp 或是 Volley 使用。实际 ImageLoader、Picasso 也都支持 okhttp、Volley。

(5) 内存友好
① Glide 的内存缓存有个 active 的设计 
从内存缓存中取数据时,不像一般的实现用 get,而是用 remove,再将这个缓存数据放到一个 value 为软引用的 activeResources map 中,并计数引用数,在图片加载完成后进行判断,如果引用计数为空则回收掉。

② 内存缓存更小图片 
Glide 以 url、viewwidth、viewheight、屏幕的分辨率等做为联合 key,将处理后的图片缓存在内存缓存中,而不是原始图片以节省大小

③ 与 Activity/Fragment 生命周期一致,支持 trimMemory

④ 图片默认使用默认 RGB565 而不是 ARGB888 
虽然清晰度差些,但图片更小,也可配置到 ARGB_888。

其他:Glide 可以通过 signature 或不使用本地缓存支持 url 过期

关于Fresco

Fresco库开源较晚,目前还没有正式的1.0版本。但其功能比前三个库都强大,比如:

•图片存储系统匿名共享内存Ashmem(Anonymous Shared Memory),并不分配Java堆内存,因此图片加载不会引起堆内存抖动;
•JPEG图像流加载(先显示图像轮廓,再慢慢加载清晰图像);
•更加完善的图像处理、显示方式;
•JPEG图像本地(native)变换尺寸,避免OOM;
•……

关于系统匿名共享内存Ashmem,会在后续的一篇关于Android的内存使用的文章中详述,这里仅作简单介绍:

在Android系统里面,Ashmem这个区域的内存并不属于Java Heap,也不属于Native Heap。当Ashmem中的某个内存空间像要被释放时候,会通过系统调用unpin来告知。但实际上这块内存空间的数据并没有被真正的擦除。如果Android系统发现内存吃紧时,就会把unpin的内存空间利用起来去存储所需的数据。而被unpin的内存空间,是可以被重新pin的,如果此时的该内存空间还没有被其他人使用的话,就节省了重新往Ashmem重新写入数据的过程了。所以,Ashmem这个工作原理是一种延迟释放。