Android Glide源码剖析系列(一)图片加载请求如何感知组件生命周期


Glide源码剖析系列

  • Android Glide源码剖析系列(一)图片加载请求如何感知组件生命周期
  • Android Glide源码剖析系列(二)Glide如何管理图片加载请求
  • Android Glide源码剖析系列(三)深入理解Glide图片加载流程
  • Android Glide源码剖析系列(四)缓存机制及其原理

为什么选择Glide?

  • 多种图片格式的缓存,适用于更多的内容表现形式(如Gif、WebP、缩略图、Video)
  • 生命周期集成(根据Activity或者Fragment的生命周期管理图片加载请求)Glide可以感知调用页面的生命周期,这就是优势
  • 高效处理Bitmap(bitmap的复用和主动回收,减少系统回收压力)
  • 高效的缓存策略,灵活(Picasso只会缓存原始尺寸的图片,Glide缓存的是多种规格),加载速度快且内存开销小(默认Bitmap格式的不同,使得内存开销是Picasso的一半)

小结:支持图片格式多;Bitmap复用和主动回收;生命周期感应;优秀的缓存策略;加载速度快(Bitmap默认格式RGB565)

Glide简单使用

Glide.with(this)
        .load("https://t7.baidu.com/it/u=3779234486,1094031034&fm=193&f=GIF")
        .into(imageView);

源码分析

我们以Gide.with(activity)方法为切入点开始分析源码

  @NonNull
  public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity); 
  }

只需要一行代码,两步轻松获取RequestManager实例

第一步、getRetriever(activity):获取到RequestManagerRetriever实例

  //1. 单例模式创建Glide实例
  //2. 获取RequestManagerRetriever实例
  @NonNull
  private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    // Context could be null for other reasons (ie the user passes in null), but in practice it will
    // only occur due to errors with the Fragment lifecycle.
    Preconditions.checkNotNull(
        context,
        "You cannot start a load on a not yet attached View or a Fragment where getActivity() "
            + "returns null (which usually occurs when getActivity() is called before the Fragment "
            + "is attached or after the Fragment is destroyed).");
    return Glide.get(context).getRequestManagerRetriever();  //分两步分析
  }

1.1 使用单例模式获取Glide实例

  public static Glide get(@NonNull Context context) {
    if (glide == null) {
      GeneratedAppGlideModule annotationGeneratedModule =
          getAnnotationGeneratedGlideModules(context.getApplicationContext());
      synchronized (Glide.class) {
        if (glide == null) {
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }
    return glide;
  }

1.2 继续追踪调用链:checkAndInitializeGlide() -> initializeGlide()

  private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
    ……
    Glide glide = builder.build(applicationContext);  //建造者模式创建Glide实例
    ……
    Glide.glide = glide;
  }

1.3 最终调用GlideBuilder.build()方法构建Glide实例

  @NonNull
  Glide build(@NonNull Context context) {

   //此处省略初始化默认配置信息代码
    ……

    //创建实例并赋值给Glide成员变量requestManagerRetriever 
    //这里传入的requestManagerFactory是用来创建RequestManager的工厂,第2步分析
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory, experiments);

    return new Glide(
        context,
        engine,
        memoryCache,
        bitmapPool,
        arrayPool,
        requestManagerRetriever,
        connectivityMonitorFactory,
        logLevel,
        defaultRequestOptionsFactory,
        defaultTransitionOptions,
        defaultRequestListeners,
        experiments);
  }

获取RequestManagerRetriever小结:

  • RequestManagerRetriever的创建是在Glide的初始化过程中完成的;
  • RequestManagerRetriever构造方法内传入requestManagerFactory,用来创建RequestManager

第二步、get(activity) 创建并返回RequestManager 实例

  @NonNull
  public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) { 
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      frameWaiter.registerSelf(activity);
      FragmentManager fm = activity.getSupportFragmentManager();
      return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }

2.1 如果当前线程不是主线程,直接转到get(activity.getApplicationContext())中执行;否则继续调用supportFragmentGet()方法

  @NonNull
  private RequestManager supportFragmentGet(
      @NonNull Context context,
      @NonNull FragmentManager fm,
      @Nullable Fragment parentHint,
      boolean isParentVisible) {
    SupportRequestManagerFragment current = getSupportRequestManagerFragment(fm, parentHint);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      // TODO(b/27524013): Factor out this Glide.get() call. (移除此处的Glide.get())
      Glide glide = Glide.get(context);
      //工厂模式创建requestManager,关于factory见分析2.2
      requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      if (isParentVisible) {
        requestManager.onStart();
      }
      current.setRequestManager(requestManager);  //requestManager存储到隐藏的Fragment
    }
    return requestManager;
  }

2.2 RequestManagerFactory 初始化过程

#RequestManagerRetriever.java
  //默认RequestManagerFactory 
  private static final RequestManagerFactory DEFAULT_FACTORY =
      new RequestManagerFactory() {
        @NonNull
        @Override
        public RequestManager build(
            @NonNull Glide glide,
            @NonNull Lifecycle lifecycle,
            @NonNull RequestManagerTreeNode requestManagerTreeNode,
            @NonNull Context context) {
          return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
        }
      };

  public RequestManagerRetriever(
      @Nullable RequestManagerFactory factory, GlideExperiments experiments) {
    this.factory = factory != null ? factory : DEFAULT_FACTORY;  //默认使用DEFAULT_FACTORY
    handler = new Handler(Looper.getMainLooper(), this /* Callback */);

    frameWaiter = buildFrameWaiter(experiments);
  }

默认使用DEFAULT_FACTORY来创建RequestManager,见2.1requestManager = factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);

2.3 RequestManager构造方法

#RequestManager.java
  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    //省略其他代码
    if (Util.isOnBackgroundThread()) {
      Util.postOnUiThread(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);
  }

  private final Runnable addSelfToLifecycle =
      new Runnable() {
        @Override
        public void run() {
          lifecycle.addListener(RequestManager.this);
        }
      };

把当前RequestManager添加到lifecycle,lifecycle是ActivityFragmentLifecycle类型,在SupportRequestManagerFragment 构造方法中创建,后文会介绍SupportRequestManagerFragment类。

重点类总结:

RequestManager implements LifecycleListener
  • 操作和管理Glide加载图片的请求
  • 实现LifecycleListener接口,根据Activity、Fragment生命周期变化和网络状态来控制图片加载流程
  • 由RequestManagerRetriever统一创建和管理,创建时使用工厂模式
RequestManagerRetriever
  • 作用是创建和复用RequestManager:使用RequestManagerRetriever.RequestManagerFactory工厂创建RequestManager,复用SupportRequestManagerFragment 中已有的RequestManager
  • 在Glide初始化时创建
SupportRequestManagerFragment 无视图的Fragment
  • 安全存储RequestManager,由RequestManagerRetriever负责绑定
  • 添加到当前Activity,利用SupportRequestManagerFragment 的生命周期变化来控制图片的加载流程

到目前为止,我们了解了大致的框架结构,接下来正式进入到本文的主题

RequestManager如何感知组件的生命周期

我们知道感知生命周期的手段是添加隐藏的SupportRequestManagerFragment,继续查看RequestManagerRetriever#getSupportRequestManagerFragment源码:

#RequestManagerRetriever.java

  /** Pending adds for SupportRequestManagerFragments. */
  @VisibleForTesting
  //缓存已经添加的隐藏SupportRequestManagerFragment
  final Map pendingSupportRequestManagerFragments = new HashMap<>();

  @NonNull
  private SupportRequestManagerFragment getSupportRequestManagerFragment(
      @NonNull final FragmentManager fm, @Nullable Fragment parentHint) {
    //1. 检查是否已经添加了隐藏的SupportRequestManagerFragment ,使用HashMap缓存SupportRequestManagerFragment 
    // 2. 查找FragmentManager 中是否有可以复用的SupportRequestManagerFragment 
    //如果都没有找到,创建一个新的SupportRequestManagerFragment,
    //并且添加到pendings列表&&提交到FragmentManager
    SupportRequestManagerFragment current = pendingSupportRequestManagerFragments.get(fm);
    if (current == null) {
      current = (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
      if (current == null) {
        current = new SupportRequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        pendingSupportRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

现在隐藏的SupportRequestManagerFragment已经添加成功,继续分析SupportRequestManagerFragment.java源码

  private final ActivityFragmentLifecycle lifecycle;

  //构造方法
  public SupportRequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }

  @VisibleForTesting
  @SuppressLint("ValidFragment")
  public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
  }

  ……

  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }

  @Override
  public void onStop() {
    super.onStop();
    lifecycle.onStop();
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    lifecycle.onDestroy();
    unregisterFragmentWithRoot();
  }

新建一个ActivityFragmentLifecycle实例赋值给SupportRequestManagerFragment的lifecycle成员变量,查看ActivityFragmentLifecycle类

class ActivityFragmentLifecycle implements Lifecycle {
//储存LifecycleListener的列表
  private final Set lifecycleListeners =
      Collections.newSetFromMap(new WeakHashMap());
  private boolean isStarted;
  private boolean isDestroyed;

  /**
   * 向lifecycleListeners列表添加LifecycleListener 
   */
  @Override
  public void addListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.add(listener);
    //添加完成后,根据状态执行对应的回调方法
    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }

  @Override
  public void removeListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.remove(listener);
  }

  void onStart() {    //遍历执行onStart
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }

//与onStart类似
  void onStop() {
    ……
  }
  void onDestroy() {
     ……
  }
}

使用观察者模式,在组件生命周期发生变化的时候回调相应的操作方法。这一切都是框架帮助咱们完成的,在RequestManager构造函数中把自身加入到ActivityFragmentLifecycle的成员变量lifecycleListeners中。

#RequestManager.java
  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    //省略其他代码
    if (Util.isOnBackgroundThread()) {
      Util.postOnUiThread(addSelfToLifecycle);  //切换到主线程执行
    } else {
      lifecycle.addListener(this);  //添加到ActivityFragmentLifecycle成员变量lifecycleListeners
    }
    lifecycle.addListener(connectivityMonitor);
  }

  private final Runnable addSelfToLifecycle =
      new Runnable() {
        @Override
        public void run() {
          lifecycle.addListener(RequestManager.this);  //添加到ActivityFragmentLifecycle成员变量lifecycleListeners
        }
      };

监听组件生命周期流程汇总:

  1. 创建无试图SupportRequestManagerFragment 绑定到当前Activity;
    SupportRequestManagerFragment 持有RequestManager实例,RequestManager实例由RequestManagerRetriever创建并传递给SupportRequestManagerFragment ;

  2. RequestManager持有ActivityFragmentLifecycle引用,在SupportRequestManagerFragment 构造方法中产生并传递给RequestManager;
    RequestManager在构造函数中把自己加入到ActivityFragmentLifecycle.lifecycleListeners列表

  3. 生命周期同步过程,以Activity调用onStart()为例:

(1)Activity调用onStart()
(2)SupportRequestManagerFragment调用onStart()

  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart(); //==ActivityFragmentLifecycle.onStart()
  }

(3)ActivityFragmentLifecycle#onStart()

  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart(); //==RequestManager.onStart()
    }
  }

(4)RequestManager#onStart()

  @Override
  public synchronized void onStart() {
    resumeRequests();  //启动图片加载请求
    targetTracker.onStart();  //添加到TargetTracker,统一管理targets响应组件生命周期
  }

图片加载时感知组件生命周期全过程END

结语

本文我们以一个图片加载请求为例,大致了解了Glide感知组件生命周期的原理,但是实际项目中必然会有许多图片加载请求同时存在,所以必须要有一个机制来统一管理这些图片请求,这样才能在组件生命周期变化时改变这些请求的状态。

关于图片加载请求如何加入到请求列表?Glide又是如何管理这些请求?下一篇文章继续分析!

Android Glide源码解析系列(二)Glide如何管理图片加载请求

你可能感兴趣的:(Android Glide源码剖析系列(一)图片加载请求如何感知组件生命周期)