Glide 系列二:Glide.with() 源码解密
本文概述:
- 文章介绍了Glide 框架整体架构设计思路、Glide.with() 源码详细执行流程,Glide.with() 参数转换分析、怎么实现FragmentActivity (入参) ---> RequestManager (返回值)、Glide 为什么要重载with()、Glide 源码在主/子线程的执行逻辑,空白Fragment 分析;
整体架构设计思路 :
-
图示说明:
- 矩形为接口,圆角矩形为Java 类
- 红色为主线程调用流程,绿色为子线程调用流程
详细源码分析流程
关键代码:
Glide.with(this).load(URL).into(imageView)
参数分析:this
-
指代当前环境:this == FragmentActivity
- 继承关系:MainActivity ---> AppCompatActivity ---> FragmentActivity
源码入口:Glide.with()
-
入口源码:
@NonNull public static RequestManager with(@NonNull FragmentActivity activity) { return getRetriever(activity).get(activity); }
- 参数变化:FragmentActivity(入参) ---> RequestManager (返回值)
- 观察Glide 类结构:多个with() 重载可适配不同场景
怎么实现FragmentActivity (入参) ---> RequestManager (返回值)
-
RequestManager 里面存在工厂设计模式
-
进入getRetriever()
- 参数变化:Context ---> RequestManagerRetriever (返回值)
-
进入RequestManagerRetriever().get(Activity)
- 参数变化:Activity ---> RequestManager
Glide 为什么要重载with() :Glide 作用域
-
业务代码:
override fun onCreate(xxx){ super.onCreate() //主线程使用Glide Glide.with(this).load(URL).into(imageView) //子线程使用Glide thread{//这就相当于Java 中的new Thread() Glide.with(this).load(URL).into(imageView) } }
-
子线程与主线程的区别:作用域不同
-
子线程作用域:application
- 其与整个app 绑定;当app 消亡,子线程Glide 才失效;
- 此时不会设计空白Fragment 覆盖,这是就无法监听
-
主线程作用域:根据实参变化
-
基础设计:空白Fragment 绑定的当前Activity ;
-
基本情况:
- 当传入View ,实际作用域可能为Activity、Fragment ;
- 当传入Fragment,实际作用域就为Fragment ;
- 当传入Activity ,实际作用域就为Activity ;
-
特殊情况:
- 传入ServiceContext() 、ApplicationContext ,此时实际作用域为Application,后续流程跟子线程相同;
-
-
主线程执行逻辑
-
业务代码
override fun onCreate(xxx){ super.onCreate() //主线程使用Glide Glide.with(this).load(URL).into(imageView) }
-
执行逻辑:
-
Glide.with(this) ---> RequestManager(FragmentActivity)
public RequestManager get(@NonNull FragmentActivity activity) { //是否是子线程 ---> 按照子线程逻辑走 if (Util.isOnBackgroundThread()) { return get(activity.getApplicationContext()); } else { Util.assertNotDestroyed(activity); //此时,空白Fragment 覆盖操作 FragmentManager fm = activity.getSupportFragmentManager(); return supportFragmentGet(activity, fm); } }
-
子线程执行逻辑
-
业务代码:
override fun onCreate(xxx){ super.onCreate() //子线程使用Glide thread{//这就相当于Java 中的new Thread() Glide.with(this).load(URL).into(imageView) } }
-
执行逻辑:子线程无空白Fragment 覆盖做任何的
-
thread{Glide.with(this)} ---> RequestManager.get(Context)
//RequestManager.get(Context) public RequestManager get(@NonNull Context context) { if (context == null) { throw new IllegalArgumentException("xxx"); } else if (Util.isOnMainThread() && !(context instanceof Application)) { if (context instanceof FragmentActivity) { // 进入FragmentActivity的get函数 return get((FragmentActivity) context); } else if (context instanceof Activity) { // 进入Activity的get函数 return get((Activity) context); } else if (context instanceof ContextWrapper && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) { // 继续递归寻找 匹配合适的 return get(((ContextWrapper) context) .getBaseContext()); } } // 上述判断都不满足 return getApplicationManager(context); }
-
-
问题:
-
为什么子线程的作用域是Application?
- 猜想:没法正常得到主线程环境
-
传入View 时,Fragment 是添加到Fragment 上,还是Activity 上?
- 根据传入的起点不同,而不同;这个View 是从Fragment 中传入的以及这个View 是从Activity 中传入的
-
空白Fragment 分析
-
存在意义:管理生命周期
-
触发逻辑:
- Activity.onStop() ---> 空白Fragment.onStop() ---> RequestManager.onStop() ---> 停止掉ImageViewTarget
-
-
源码分析入口:
- 第一步
RequestManager.get(xxx){ //进入这个 return supportFragmentGet(activity, fm); }
- 第二步
RequestManager.supportFragmentGet(xxx){ //从 FragmentManager 中获取 SupportRequestManagerFragment(空白) SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm); }
-
源码文件:SupportRequestManagerFragment.java
- 这是无UI 的Fragment:没有 onCreateView()
- 只有onStart()、onStop()、onDestroy()、onDetach();通过接口回调的方式回调给外界,做整个生命周期的绑定
- 存在接口lifecycle
public interface Lifecycle { void addListener(@NonNull LifecycleListener listener); void removeListener(@NonNull LifecycleListener listener); }
-
其中的LifecycleListener :这就是实际操作的接口
-
查看lifecycle 接口实现类(第一个为主线程使用,第二个子线程使用)