前言
Glide 网络请求为Okhttp时需要添加OkHttp依赖,如果需要自定义的OkHttpClient,需要做类似代码中registerComponents()方法中操作。默认Glide会为我们创建一个默认的OkHttpClient。
实例创建
Glide#with方法,Glide#get获取一个Glide实例,通过double check方式创建单实例。通过反射的方式创建GeneratedAppGlideModuleImpl实例。构造函数的参数是ApplicationContext。
- 解析Manifest中的Glide实例(已经废弃),通过注解的方式实现自定义配置。
- 通过注解生成代码,过来Manifest中的Module
- 构建Glide中GlideBuilder通过applyOptions()传递给每一个manifest中的Moudle和注解生成的module,对Glide构建时自定义
- 通过
GlideBuilder#build()完成Glide创建 - 通过
ApplicationContext#registerComponentCallbacks()监听应用配置改变和低内存的状态监听,通知给glide实例。
Glide处理缓存对象
- SourceExecutor:通过CPU核心数计算线程数,最大4个线程
- DiskCacheExecutor:线程数为1
- AnimatorExecutor:线程数是SourceExecutor的一半
- MemorySizeCalculator:计算各种缓存内存的大小
- ConnectivityMonitorfactor:在有网络状态情况下监听权限的情况,监听网络状态
- BitmapPool:bitmap缓存,Android 8 及以上版本缓存大小是0;在Android 8 以下版本缓存大小是4倍屏幕大小图片所需要的内存。
- ArrayPool:存储int数组和byte数组的缓存,大小是4M;如果是低内存大小是2M
- MemoryCache:Resource对象的缓存,Glide中很多对象是Resource,缓存大小是2倍屏幕大小图片所需要的内存
- DiskCacheFactory:本地磁盘缓存处理
- Engine:请求引擎
- RequestManagerRetriever:查找对应的Context的Requestmanager
MemorySizeCalculator
计算各种内存大小:BitmapPool,ArrayPool,MemoryCache等
Android 8.0以上的设备,Bitmap配置使用的是Config.HARDWARE,占用的是显存,不占用内存,Bitmap数据也无法修改,所以不缓存。
LruBitmapPool 是BitmapPool实现,大小是4倍屏幕大小图片占用的内存
- 检查Bitmap的状态,不为空,没有被回收,可以被修改,内存占用大小,小于当前BitmapPool的最大缓存值。
- 通过
strategy#put方法完成缓存,strategy实现类通过SizeConfigstrategy - 更新当前缓存的Bitmap数量和占用的缓存大小
- 通过evict()方法,检查是否达到了最大缓存值,如果达到最大缓存值,清除旧的Bitmap
处理过程:
- 通过Bitmap大小和配置计算Key,Keypool最多缓存20个key,如果没有缓存就创建一个新的,key的Hashcode根据Bitmap配置和大小计算的
- 通过GroupLinkedMap缓存Bitmap,类似于Hashmap,HashMap会移除相同的Key的数据。GroupedLinkMap不会移除相同的Key的数据,把相同的Key的数据以列表的形式串联起来。HashMap的get方法不会移除数据,而GroupLinkedMap的get方法会移除数据
- 重新计算当前配置Bitmap的数量,存储在sortedSizes中,它是一个HashMap,Key是Bitmap.Config,value是一个Map
<Integer,Integer>(key是Bitmap大小,Value是对应的数量)
GroupedLinkedMap,类似LinkedEntry,它是一个双向循环的链表,存储了Value列表,LinkedEntry的新旧是通过双向的环状链表来排序。
LruArrayPool
LruArrayPool和LruBitmapPool类似,用来缓存int数组和byte数组的缓存池。
- 通过getAdapterFromtype()查找对应数组的Adapter
- 计算数组内存占用大小
- 如果数组过大,跳过缓存,直接退出方法;否则,继续操作
- 通过数组长度和arrayClass计算key
- 通过GroupedLinkedMap#put方法来缓存
- 更新缓存的数量
- 更新缓存占用的大小
- 计算是否达到缓存上限,达到上限移除最久的缓存,直到没有超过上限为止
总结
Glide优秀在于内存缓存和磁盘缓存,特别是磁盘缓存。