图片内存优化都是一些比较琐碎的点,这里记录几个开发中常遇到的。
XML中的可优化点
1 尽量少使用selector
使用selector来做选中的效果很方便,但是有一点小问题就是selector会一次性将两张图片一块儿加载到内存,如果页面中Button很多且图片大的话就会占用相当一部分内存。
解决方案:解决方案就是利用onTouch()处理,监听down、move事件来做为pressed状态处理,然后up事件恢复默认图片。如果你觉的很麻烦的话,没关系我也这么觉的。。。。即便是可以做统一处理
2 尽量不要AnimationDrawable
AnimationDrawable也就是我们常说的帧动画,这个动画是需要配置每一帧的图片都加载到内存。
3 不要给Activity设置背景图
4 使用ViewStub来展示图片
如果图片比较大且不是必要出现时可以考虑使用ViewStub来处理
Bitmap相关
1 Bitmap使用完之后及时recycle掉
2 将Bitmap大小设置成与ImageView大小相当,通过isSimpleSize属性来处理
3 选择合适的位图格式,位图格式有ARGB8888、ARGB4444,RGB565、ALPHA_8这4种,所占内存字节数分别是4、2、2、1字节,Android默认位图格式时ARGB8888,如果对图片质量要求不高的时候可以使用ARGB4444
网络图片
Glide的缓存模型时怎么样的?大致来说是两层内存缓存和资盘缓存,但是内存缓存又分为了两层分别是active和lru,所以总的来说是三层吧。
1 active
这层利用的是HashMap但是重点是HashMap持有的是弱引用,这样就能保证这部分图片在GC时候被回收,而这部分图片就是表示正在使用的图片。active里面的对象生命周期都比较短,没有设置容量上限,但是LRU就有
2 lru
这部分就是LRUCache,这个部分的空间大小默认是屏幕宽的像素值x高的像素值x4这么多字节
3 磁盘缓存
当active和lru都没有获取到图片的时候,就尝试从磁盘缓存中获取,磁盘缓存是IO操作所以必然会放到线程里面去做。EngineJob就是一个Runnable
三者之前的关系又是怎么样的呢?有下面几点
1 首先从active中读,如果没有就从lru中读,如果lru中也没有的话就会从磁盘里面读。
2 如果active中没读取到,但是从lru中读取到了,则会在active中添加同事会移除lru中的该图片对象。反之如果active中的图片不再被使用时,会从active中移除同时会添加到lru中
3 当active中和lru中都没有读取到图片,则从磁盘中读完成而之后会添加到active中
Glide早期的版本是先从lru中读,然后再放到active中。
网友评论