Glide 系列二:Glide.with() 解密

502 阅读3分钟

Glide 系列二:Glide.with() 源码解密

本文概述:

  • 文章介绍了Glide 框架整体架构设计思路、Glide.with() 源码详细执行流程,Glide.with() 参数转换分析、怎么实现FragmentActivity (入参) ---> RequestManager (返回值)、Glide 为什么要重载with()、Glide 源码在主/子线程的执行逻辑,空白Fragment 分析;

整体架构设计思路 :

  • 图示说明:

    • 矩形为接口,圆角矩形为Java 类
    • 红色为主线程调用流程,绿色为子线程调用流程

Glide1

详细源码分析流程

关键代码:

 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() 重载可适配不同场景

    image-20220817013418414

怎么实现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()

    image-20220817025251327

    • 只有onStart()、onStop()、onDestroy()、onDetach();通过接口回调的方式回调给外界,做整个生命周期的绑定

    image-20220817025434393

    • 存在接口lifecycle
     public interface Lifecycle {
     ​
         void addListener(@NonNull LifecycleListener listener);
     ​
         void removeListener(@NonNull LifecycleListener listener);
     ​
     }
    
    • 其中的LifecycleListener :这就是实际操作的接口

      image-20220817170702791

    • 查看lifecycle 接口实现类(第一个为主线程使用,第二个子线程使用)

    image-20220817170209572