Glide的生命周期管理
主要分为三个层次的生命周期:Activity & 网络 & 内存。
我们一般认为,应该及时取消不必要的加载请求,这很耗费资源,但在Glide这并不是必须的操作。因为 Glide 会在页面生命周期 / 网络变化时,自动取消加载或重新加载。没错,就是这么牛逼。
- 页面生命周期
当页面不可见时暂停请求;页面可见时恢复请求;页面销毁时销毁请求。 - 网络连接状态
如果从 URL 加载图片,Glide 会监听设备的连接状态,并在重新连接到网络时重启之前失败的请求。 - 内存状态
Glide 会监听内存状态,并根据不同的 level 来释放内存。
为什么要监听页面生命周期?
主要基于以下两个目的: - 以确保优先处理前台可见的 Activity / Fragment,提高资源利用率;
- 在有必要时释放资源以避免在应用在后台时被杀死,提高稳定性。
三种生命周期作用域
还记得Glide使用的第一句吗,Glide.with(参数),
with()方法可以接收Context、Activity或者Fragment类型的参数。
先说结论,根据传入的参数不同,将对应于 Application & Activity & Fragment 的作用域,具体如下:
这里不细节分析源码实现,我们只需要知道,不同参数通过重载方法,作用于不同的作用域
生命周期绑定
1、从 FragmentManager 中获取 SupportRequestManagerFragment;
2、从该 Fragment 中获取 RequestManager;
3、首次获取,则实例化 RequestManager,后续从同一个 SupportRequestManagerFragment 中都获取的是这个 RequestManager。
不拘泥于细节,关键在于SupportRequestManagerFragment
其实就是三步走战略。1.1 尝试获取FRAGMENT_TAG对应的 Fragment
1.2 尝试从临时记录中获取 Fragment
-
1.3 实例化 Fragment
- 1.3.1 创建对象
- 1.3.2 如果父层可见,则调用 onStart() 生命周期
- 1.3.3 临时记录映射关系(HashMap)
- 1.3.4 提交 Fragment 事务
- 1.3.5 post 一个消息
- 1.3.6 移除临时记录中的映射关系
这里具体分析一下上面这些晦涩的语句,注意设计的思路重点,就是这个SupportRequestManagerFragment,这个隐藏SupportRequestManagerFragment,这个并不可见的SupportRequestManagerFragment。
这里为什么要添加一个隐藏的Fragment呢?
Glide并没有办法知道Activity的生命周期,于是Glide就使用了添加隐藏Fragment的这种小技巧,相当于通过这个隐藏的fragment与对应的Activity建立了联系,因为Fragment的生命周期和Activity是同步的,如果Activity被销毁了,Fragment是可以监听到的,这样Glide就可以捕获这个事件并停止图片加载了。
这里又有一个设计点,临时记录,它是为了干什么呢?
在提交 Fragment 事务之前,为什么需要先保存记录?
这是 为了避免 SupportRequestManagerFragment 在一个作用域中重复创建。
因为commitAllowingStateLoss()是将事务 post 到消息队列中的,也就是说,事务是异步处理的,而不是同步处理的。假设没有临时保存记录,一旦在事务异步等待执行时调用了Glide.with(...),就会在该作用域中重复创建 Fragment。
生命周期监听
从上面的分析我们得知,Glide 为每个Activity 和 Fragment 作用域创建了一个无界面的 Fragment,这里我们就来分析 Glide 如何监听这个无界面 Fragment 的生命周期。
首先先提到一个概念,Lifecycle,大家可以粗略的把它理解为 移动APP页面的状态
其实说起来也是三步走战略,
1、在创建Fragment的时候会创建ActivityFragmentLifecycle对象;
2、在Fragment生命周期的方法中会调用Lifecycle的相关方法来通知RequestManager;
3、LifecycleListener 是一个接口,RequestManager实现了这个接口,Lifecycle最终是调用了lifecycleListener来通知相关的实现类的,也就是RequestManager。
生命周期回调
这个就非常简单了,也就是上述的RequestManager实现了LifecycleListener接口后,在对应的方法中,作出相应的处理。
主要关注以下几点:
- 1、页面不可见时暂停请求(onStop() )
- 2、页面可见时恢复请求(onStart() )
-
3、页面销毁时销毁请求(onDestroy() )
网络连接状态监听
这个逻辑很简单,在刚才所说的RequestManager的构造器中,会构建一个ConnectivityMonitor对象,它的默认构造工厂是DefaultConnectivityMonitorFactory,如果有网络监听权限,
则实例化DefaultConnectivityMonitor,在onStart()时注册广播监听器,而在onStop()时注销广播监听器。在RequestManager中根据网络状态进行相应的操作。
听起来有点拗口,简而言之,如果应用有监控网络状态的权限,那么 Glide 会监听网络连接状态,在页面可见时注册广播监听器,而在页面不可见时注销广播监听器,并在网络重新连接时重新启动失败的请求。
内存状态监听
这个的实现也非常简单的的,在构建 Glide 时,会调用registerComponentCallbacks()进行全局注册, 系统在内存紧张的时候回调onTrimMemory(level)。
而 Glide 则根据系统内存紧张级别(level)进行相应的回收,而 RequestManager 在 TRIM_MEMORY_MODERATE 级别会暂停请求。