《Glide 4.x工作总体执行流程概述》
《Glide 4.x之请求网络图片数据流程解析》
《Glide 4.x之ModelLoader简单分析》
《Glide 4.x添加自定义组件原理》

在《Glide 4.x工作总体执行流程概述》一篇博文中我们直到Glide加载图片的步骤主要由两个:
1、通过RequestBuilder对象创建Request对象
2、将Request对象交给RequestManager来管理,并发起请求
上面两个步骤的主要在into方法中得到体现:

private <Y extends Target<TranscodeType>> Y into(@NonNull Y target,@Nullable RequestListener<TranscodeType> targetListener,RequestOptions options) {//、创建request对象Request request = buildRequest(target, targetListener, options);//获取target对象的Request对象Request previous = target.getRequest();//如果同一个target的请求一样if (request.isEquivalentTo(previous)) {if (!Preconditions.checkNotNull(previous).isRunning()) {//如果同一个target的同一个request没有执行,就执行而不是创建新的previous.begin();}return target;}//清除target之前的的的requestrequestManager.clear(target);//为target设置新的requesttarget.setRequest(request);//设置新的reqesutrequestManager.track(target, request);return target;
}

into方法的主要核心是:
1、先创建一个request对象
2、判断同一个target(ImageView)上次发起的网络请求和步骤1创建的请求是否是同一个,如果是的话就继续使用前一次发起的请求
3、如果步骤1创建的请求和上次发起的请求不一样,比如URL改变了,那么就让target清除旧的请求(哪怕是旧的请求isRunning状态也需要中断了),并记录最新的请求,并且将最新的请求交给requestManager来管理(track方法):

 TargetTracker targetTracker = new TargetTracker();RequestTracker requestTracker;void track(Target<?> target, Request request) {//将target加入TargetTracker的一个set集合targetTracker.track(target);//将request交给RequestTracker,并执行requestTracker.runRequest(request);
}

track方法的核心就是将target和Request对象分别交给TargetTracker和RequestTracker处理,其中targetTracker的track方法是将Target对象添加到一个set集合里面;而requestTracker的runReqeust方法做了如下操作:
1、先将request对象添加到一个里面
2、如果已经处于暂停状态,则将request集合添加到 pendingRequests这个集合中,否则则执行request的begin方法,runReqeust的代码实现如下:

Set<Request> requests =Collections.newSetFromMap(new WeakHashMap<Request, Boolean>());List<Request> pendingRequests = new ArrayList<>();public void runRequest(Request request) {//将request加入集合requests.add(request);//如果没有暂停,那么if (!isPaused) {request.begin();} else {//放入pending集合中等待下次开始执行pendingRequests.add(request);}
}

先来看看RequestTracker方法都提供了哪些public方法:

从上图来看ReqeustTrack方法提供了restartRequest、resumeRequest等控制Request对象生命周期的方法,从代码实现来看RequestTracker倒是真正的请求管理者(RequestManager),简单看看restartRequest都是做了什么:

  public void restartRequests() {//遍历方法for (Request request : Util.getSnapshot(requests)) {if (!request.isComplete() && !request.isCancelled()) {//先暂停后启动request.pause();if (!isPaused) {//启动request.begin();} else {pendingRequests.add(request);}}}}

上面的isPause用来判断请求是否暂停,且RequestTracker提供了pauseReqeusts 方法,另外该对象交给RequestManager 来管理,换句话说ReqeustManager来代理管理Request的生命周期方法,Request接口提供了如下几个方法:

所以看看ReqeustManager都提供了哪些方法来管理Request的生命周期:

而ReqeustTracker的restartRequests方法则是在RequestManager的嵌套类RequestManagerConnectivityListener的onConnectivityChanged方法调用:

  @Overridepublic void onConnectivityChanged(boolean isConnected) {if (isConnected) {requestTracker.restartRequests();}}

那么RequestManager里面这些管理请求的方法都是什么时候调用的呢?要知道我们在使用Glide的时候在客户端并没有手动调用这些方法,在回答这个问题之前让我们看看Glide的重要接口LifecycleListener:

而且我们的RequestManager类就是LifecycleListener的实现类,所以进入RequestManager类里面看LifecycleListener接口的方法具体实现:

一目了然,在LifecycleListener的接口方法里面分别对应的调用了pauseRequests()方法,resumeRequets()方法等。在此需要注意一个问题,比如在onStart()方法里面也调用了targetTracker的onStart方法,那么这个方法又是来干什么呢?(此处先不讨论了,先埋个坑)
看Glide对LifecycleListener的解释我们就知道了该接口的作用:将Acitivity /Fragment的生命周期和Request的生命周期进行绑定:

An interface for listener to Fragment and Activity lifecycle events.

从上面的讲解我们看出Glide与Acitity生命周期的绑定实际上绑定的是Request对象的生命周期。

问题1:那么glide是怎么使得Activity的生命周期和Request的生命周期进行绑定的呢?

下面就来分析分析这个问题我们现在已经知道RequestManager就是LifecycleListener接口的一个实现类。

**问题2:**Glide是怎么管理或者说控制LifecycleListener方法的呢?

其实Glide里面提供了另外一个接口Lifecycle来添加和删除LifecycleListener:

而且在RequestManager的内部也有该接口的一个引用:

final Lifecycle lifecycle;private final Runnable addSelfToLifecycle = new Runnable() {@Overridepublic void run() {//将RequestManager自身添加到lifecycle方法中lifecycle.addListener(RequestManager.this);}};

RequestManager的lifecycle引用是通过构造器来初始化的:

RequestManager(Glide glide,Lifecycle lifecycle,RequestManagerTreeNode treeNode,RequestTracker requestTracker,ConnectivityMonitorFactory factory,Context context) {/*初始化lifecycle*/this.lifecycle = lifecycle;/*省略来部分代码*/connectivityMonitor =factory.build(context.getApplicationContext(),new RequestManagerConnectivityListener(requestTracker));/*通过handler来保证是在UI线程添加*/if (Util.isOnBackgroundThread()) {mainHandler.post(addSelfToLifecycle);} else {lifecycle.addListener(this);}lifecycle.addListener(connectivityMonitor);/*添加RequestManger对象添加到glide的list集合里面*/glide.registerRequestManager(this);}

上面的构造器说明了是什么时候将LifecycleListener添加到lifecycle里面的。

问题3::RequestManager是什么时候初始化的,其实这个问题应该这么问lifecycle接口是如何初始化的。
如果问题3解答出来那么本篇博文的主题:glide生命周期与Acticity 的绑定原理就一目了然了。下面就来回答这个问题:

在Glide中提供了若干个方法可以得到RequestManager对象:

在此挑with(Activity)来分析,其代码如下:

 public static RequestManager with(Activity activity) {return getRetriever(activity).get(activity);}

而要获取RequestManager则需要RequestManagerRetriever的get方法,在此我们只需要知道该类有一个factory来创建RuquestManager对象即可,至于创建的流程可阅读关于该方法的简单说明可以在《Glide 4.x工作总体执行流程概述》 了解,且RequestManagerRetriever也提供了获取RequestManager对象的重载方法:

接着继续分析RequestManagerRetriever的get(Activity) 方法:

public RequestManager get(Activity activity) {//非UI线程if (Util.isOnBackgroundThread()) {return get(activity.getApplicationContext());} else {//UI线程android.app.FragmentManager fm = activity.getFragmentManager();return fragmentGet(activity, fm, null /*parentHint*/);}}

上面的方法在UI线程的调用了fragmentGet来返回了一个RequestManager对象,其代码如下:

从上图可以看出来初始化RequestManager需要两个重要的步骤:

1、调用getRequestManagerFragment
方法初始化RequestManagerFrament对象,该对象是Fragment对象。

2、调用RequestManagerFrament的getGlideLifecycle方法获取Lifecyle对象交给RequestManager处理

到此为止,上面问题3的已经算是解答完毕!
观察源码发现RequestManagerFragment就是一个Fragment,且其内部含有一个Lifecycle的引用:

public class RequestManagerFragment extends Fragment {//ActivityFragmentLifecycle实现了Lifecycle接口private final ActivityFragmentLifecycle lifecycle;
}

通过上文我们知道RequestManager拿到Lifecycle方法后调用lifeCycle.addListener(this)将自己交给了Lifecycle。我们来看看ActivityFragmentLifecycle的addListener方法:

如上图所示我们最终将RequestManager对象添加到了ActivityFragmentLifecycle一个set集合里面。因为ActivityFragmentLifecycle本身也是一个Lifecycle,其也实现了Lifecycle的生命周期方法,如果所示:

在onStart等方法中只是遍历了set集合,然后拿出具体的LifecycleListener对象执行对应的方法而已。

通过上文的说明我们知道ActivityFragmentLifecycle对象引用交给了RequestManagerFragment这个Fragment对象来持有,所以我们在此有理由推断出Glide在Fragment的生命周期函数里面调用了ActivityFragmentLifecycle这个Lifecycle的相关方法,不信看代码:

到此为止,Glide的生命周期绑定activity 的生命周期实现原理以及讲解完毕,总的来说就是:
1、通过Fragment的生命周期函数onStart()/onStop()/onDestory()来执行Glide的Lifecycle的onStart()/onStop()/onDestory()方法

2、而上面Frament的lifecycle具体实现类就是ActivityFragmentLifecycle,其内部持有一个集合来添加LifecycleListener接口的具体实现,比如RequestManager.在glide中LifecycleListener的具体实现有如下几个类:

3、而RequestManager又是通过RequestTrack的相关方法来管理Request对象的pasue,resume,restart等

最终层层深入完成了与Acitivity生命周期的绑定。

Glide 4.x之生命周期与Activity的绑定原理详解相关推荐

  1. 基于全生命周期的主数据管理:MDM详解与实战学习02 第二章 主数据管理的内涵

    第二章 主数据管理的内涵 导读 2.1 主数据的概念 2.1.1 主数据的定义 2.1.2 主数据的特征 2.1.3 主数据的范围 1.描述实体范围 2.应用层次范围 (1)元数据 (2)引用数据 ( ...

  2. vue 加载时掉用mounted_Vue实例中生命周期created和mounted的区别详解

    前言 本文主要跟大家介绍了关于Vue实例中生命周期created和mounted区别的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 生命周期先上图 什么是生命周期 Vue ...

  3. java线程的生命周期及wait(),notify(),notifyAll()的详解分析

    1.java线程的生命周期     线程是一个动态执行的过程,它也有一个从产生到死亡的过程. (1)生命周期的五种状态 新建(new Thread)     当创建Thread类的一个实例(对象)时, ...

  4. Vue2.和Vue3.生命周期的区别,对比。 详解生命周期中的每个钩子函数,setup,

    文章目录 #1.Vue2.的生命周期与Vue3.的生命周期对比图 #1.1白色背景图是Vue2.的生命周期,黑色背景图是Vue3.的生命周期. #2.Vue2.与Vue3.的生命周期函数的不同 #2. ...

  5. 【转载】基于全生命周期的主数据管理:MDM详解与实战学习

    01 第一章概念学习 第1章 主数据管理的背景 1.1 信息时代的企业发展 1.2 数据资产 1.2.1 数据资产的概念 1.2.2 数据资产的重要性 1.2.3 数据资产现状 1.3 数据治理 1. ...

  6. vue生命周期(Life Cycle)函数详解

    生命周期函数 在 某一时刻 自动执行 的函数 生命周期是什么 生命周期(Life Cycle)的概念应用很广泛,特别是在政治.经济.环境.技术.社会等诸多领域经常出现,其基本涵义可以通俗地理解为&qu ...

  7. Spring:IOC容器Bean的生命周期的int和destro方法详解(4)

    Bean的生命周期 1)实例化Bean 对于BeanFactory容器,当客户向容器请求一个未初始化的bean时,或初始化bean的时候需要注入另一个未初始化的依赖时,容器就会调用createBean ...

  8. 基于全生命周期的主数据管理:MDM详解与实战学习03 第三章 主数据管理的关键技术

    第三章 主数据管理的关键技术 3.1 数据标准 3.1.1 数据标准的分类 3.1.2 物资类数据标准 1.国际标准 2.国内标准 3.1.3 产品数据标准 3.1.4 财务数据标准 3.2 信息分类 ...

  9. android代理生命周期,了解 Activity 生命周期

    当用户浏览.退出和返回到您的应用时,您应用中的 在生命周期回调方法中,您可以声明用户离开和再次进入 Activity 时 Activity 的行为方式.例如,如果您正构建流媒体视频播放器,当用户切换至 ...

  10. Fragment的生命周期同一Activity下不同Fragment之间的通信

    Android开发:碎片Fragment完全解析(2) Fragment的生命周期 和Activity一样,Fragment也有自己的生命周期,理解Fragment的生命周期非常重要,我们通过代码的方 ...

最新文章

  1. idea2019的安装与激活
  2. JavaScript DOM 向文档添加新的元素
  3. Hadoop应用实战100讲(一)-Hadoop进行文件压缩
  4. sql 截取_如何用 SQL 找一个女朋友?
  5. Docker环境下Java应用的最大内存和堆内存的设置
  6. gui窗口遮挡算法_软件更新丨AWTK 1.2 发布,国产开源 GUI 引擎
  7. 基于Hibernate+spring的公司网站打造中(二)
  8. 以色列:新发明大幅提高太阳能发电效率
  9. hiveserver2启动不起来_汽车一键启动只能用来打火吗 车主必须知道的几个“隐藏”技巧!...
  10. 那些年,我们一起追过的足球
  11. ----vue项目打包之浏览器存在缓存问题----
  12. Android修炼之道—布局优化( 100 喵喵币)
  13. matlab powf,科学网—MZDDE中操作数更正 - 张凯元的博文
  14. 【优化模型】求非齐次线性方程组的通解
  15. CF755F PolandBall and Gifts
  16. php 红包过期退回,RabbitMQ功能实现1- 红包未领取退回
  17. Flutter架构图
  18. @Autowired的基本使用
  19. c语言1e05,RSA加密、解密的纯C语言版本
  20. Crisis Tests China, India Ties

热门文章

  1. android 按钮换行_自定义Android自动换行的布局
  2. Javascript特效:简单的匀速平移动画
  3. mysql中dint_mysql常用操作——数据库和表的操作1(共2页)
  4. c语言全缓冲,C语言缓冲区 - osc_8b4n157m的个人空间 - OSCHINA - 中文开源技术交流社区...
  5. 让你的模型acc更上一层楼:模型trick和数据方法总结
  6. 超详细的计算机视觉竞赛汇总
  7. LeetCode之寻找峰值
  8. C++ - 操作运算符
  9. 20155209 林虹宇 Exp3 免杀原理与实践
  10. window7 32位部署django