假如让你自己写个图片加载框架,你会考虑哪些问题?

2021-01-05  本文已影响0人  陈萍儿Candy

异步加载:线程池
由于网络会阻塞,所以读内存和硬盘可以放在一个线程池,网络需要另外一个线程池,网络也可以采用Okhttp内置的线程池。
切换线程:Handler,没有争议吧
无论是RxJava、EventBus,还是Glide,只要是想从子线程切换到Android主线程,都离不开Handler。
缓存:LruCache、DiskLruCache
内存缓存:LruCache(最新数据始终在LinkedHashMap最后一个)
LruCache中维护了一个集合LinkedHashMap,该LinkedHashMap是以访问顺序排序的。
当调用get()方法访问缓存对象时,就会调用LinkedHashMap的get()方法获得对应集合元素,同时会更新该元素到队尾。
当调用put()方法时,就会在结合中添加元素,并调用trimToSize()判断缓存是否已满,如果满了就用LinkedHashMap的迭代器删除队首元素,即近期最少访问的元素。
磁盘缓存 DiskLruCache(DiskLruCache会自动生成journal文件,这个文件是日志文件,主要记录的是缓存的操作)
DiskLruCache和LruCache内部都是使用了LinkedHashMap去实现缓存算法的,只不过前者针对的是将缓存存在本地,而后者是直接将缓存存在内存。
防止OOM:软引用、LruCache、图片压缩、Bitmap像素存储位置
软引用:LruCache里存的是软引用对象,那么当内存不足的时候,Bitmap会被回收,也就是说通过SoftReference修饰的Bitmap就不会导致OOM。
当然,Bitmap被回收的时候,LruCache剩余的大小应该重新计算,可以写个方法,当Bitmap取出来是空的时候,LruCache清理一下,重新计算剩余内存;
还有另一个问题,就是内存不足时软引用中的Bitmap被回收的时候,这个LruCache就形同虚设,相当于内存缓存失效了,必然出现效率问题。
onLowMemory:当内存不足的时候,Activity、Fragment会调用onLowMemory方法,可以在这个方法里去清除缓存,Glide使用的就是这一种方式来防止OOM。
Bitmap 像素存储位置考虑:Android 3.0到8.0 之间Bitmap像素数据存在Java堆,而8.0之后像素数据存到native堆中
内存泄露:注意ImageView的正确引用,生命周期管理
通过给Activity添加自定义Fragment方式,监听生命周期,在Activity/fragment 销毁的时候,取消图片加载任务
列表滑动加载的问题:加载错乱、队满任务过多问题

上一篇 下一篇

猜你喜欢

热点阅读