美文网首页
Glide源码解读(一)-- 图片加载的生命周期

Glide源码解读(一)-- 图片加载的生命周期

作者: IN_BLACK_IN | 来源:发表于2018-02-26 17:37 被阅读0次

先来看下glide的一般使用方法

Glide.with(context).load(url).into(mImageView);

其中Glide.with(context)这一步就完成了图片加载时的生命周期绑定,可见glide调用简单,然而其在背后的逻辑却很复杂,接下来我们从源码的角度去解读glide如何用一句话完成了这么多事。

我们以context对象是Activity为例,进入到Glide.with(context) 这个方法中

RequestManagerRetriever
public RequestManager get(@NonNull Activity activity) {
  if (Util.isOnBackgroundThread()) {
    // 如果不是主线程,则context对象转为ApplicationContext,然后也不做绑定生命周期的操作,
    // 图片加载的生命周期默认为Application的生命周期
    return get(activity.getApplicationContext());
  } else {
    assertNotDestroyed(activity);
    android.app.FragmentManager fm = activity.getFragmentManager();
    return fragmentGet(activity, fm, null /*parentHint*/);
  }
}

接着进入fragmentGet方法

private RequestManager fragmentGet(@NonNull Context context,
    @NonNull android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint) {
  // 获取到一个无UI的Fragment,用来绑定Activity从而实现生命周期同步
  // 因为glide无法直接获取activity的生命周期,通过activity的FragmentManager中加入一个隐藏的fragment,
  // 因为fragment与传入的activity生命周期一致,所以只要监听这个RequestManagerFragment就能实现生命周期管理
  RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
  RequestManager requestManager = current.getRequestManager();
  ......
  return requestManager;
}

我们具体看下fragment的创建过程

RequestManagerFragment getRequestManagerFragment(
    @NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint) {
  // 由于这个Fragment是个无UI的Fragment,可以通过findFragmentByTag(FRAGMENT_TAG)去查找这个RequestManagerFragment
  // 但如果第一次进来,current就是null,如果已经创建过,可以通过fm对象找到已有的fragment对象
  // 无UI查找Fragment参考文章 http://blog.csdn.net/llp1992/article/details/41828237
  RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
  if (current == null) {
    current = pendingRequestManagerFragments.get(fm);
    if (current == null) {
      // 初始化RequestManagerFragment并且绑定FRAGMENT_TAG放入FragmentManager
      current = new RequestManagerFragment();
      ......
    }
  }
  return current;
}

接着我们进入RequestManagerFragment的构造方法中查看初始化的时候做了些什么

public class SupportRequestManagerFragment extends Fragment {
  
  public SupportRequestManagerFragment() {
    // 初始化Fragment的时候也顺便初始化了ActivityFragmentLifecycle
    this(new ActivityFragmentLifecycle());
  }

  @SuppressLint("ValidFragment")
  public SupportRequestManagerFragment(ActivityFragmentLifecycle lifecycle) {
    // lifecycle赋值
    this.lifecycle = lifecycle;
  }

  /**
   * 在构造方法中{@link #SupportRequestManagerFragment(ActivityFragmentLifecycle)}
   * 初始化lifecycle
   */
  ActivityFragmentLifecycle getGlideLifecycle() {
    return 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();
  }
}

我们可以看下上面这个类的部分代码,在初始化Fragment的时候也顺带初始化了ActivityFragmentLifecycle,并赋值给lifecycle,在fragment的生命周期方法中,比如onStart方法中,调用了lifecycle.onStart(),由于fragment和绑定的activity生命周期基本一样,这样的话lifecycle对象也就带有刚开始传入Glide.with(context)这个context对象的生命周期,可以通过fragment对象的getGlideLifecycle()方法获取到这个带有生命周期的自定义类的对象。

到这里,基本就知道了glide怎么去获取到当前上下文对象的生命周期变化,接下去我们继续分析,glide获取到生命周期后去做了些什么事情。

首先来看下这个自定义的生命周期自定义类

class ActivityFragmentLifecycle implements Lifecycle {
  
  @Override
  public void addListener(LifecycleListener listener) {
    lifecycleListeners.add(listener);

    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }

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

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

  void onStop() {
    isStarted = false;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }

  void onDestroy() {
    isDestroyed = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
  }
}

public interface Lifecycle {
  void addListener(LifecycleListener listener);
  void removeListener(LifecycleListener listener);
}

ActivityFragmentLifecycle 实现了Lifecycle,对外暴露一个addListener方法,可以监听生命周期的变化。到这里,监听生命周期的准备工作都已经完成,就等其他想要使用的地方去实现这个监听器了,所以我们回过头去看下哪里实现了这个监听器。


接下来我们回到上文中的fragmentGet方法,刚刚看了部分代码,现在我把这个方法的全部代码贴出来

private RequestManager fragmentGet(@NonNull Context context,
    @NonNull android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint) {
  // 获取到一个无UI的Fragment,用来绑定Activity从而实现生命周期同步
  // 因为glide无法直接获取activity的生命周期,通过activity的FragmentManager中加入一个隐藏的fragment,
  // 因为fragment与传入的activity生命周期一致,所以只要监听这个RequestManagerFragment就能实现生命周期管理
  RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
  RequestManager requestManager = current.getRequestManager();
  if (requestManager == null) {
    // 初始化了图片加载引擎等内容,为后面的图片加载做准备
    Glide glide = Glide.get(context);
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
    current.setRequestManager(requestManager);
  }
  return requestManager;
}

上面我们用大篇幅解析了这一行代码 RequestManagerFragment current = getRequestManagerFragment(fm, parentHint),接下去我们接着走下去。接着执行 RequestManager requestManager = current.getRequestManager(),当第一次执行 current.get 方法的时候,返回的 requestManager 对象是null,所以我们重点分析下if里面的代码块。

我们进入factory.build(glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context)方法中

public interface RequestManagerFactory {
  @NonNull
  RequestManager build(
      @NonNull Glide glide,
      @NonNull Lifecycle lifecycle,
      @NonNull RequestManagerTreeNode requestManagerTreeNode,
      @NonNull Context context);
}

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) {
    // 在这里初始化RequestManager
    return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
  }
};

其中factoryRequestManagerRetriever构造方法中被赋值:this.factory = factory != null ? factory : DEFAULT_FACTORY,故 factory.build 最终执行的是return new RequestManager(glide, lifecycle, requestManagerTreeNode, context)。其中lifecycle正是我们前面创建fragment生成的带有生命周期的自定义类。

我们进入RequestManager的构造方法,查看下RequestManager整个类的关键代码

public class RequestManager implements LifecycleListener {

  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {

    this.glide = glide;
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;
    this.context = context;

    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      // RequestManager 实现了LifecycleListener,然后和lifecycle实现了绑定
      lifecycle.addListener(this);
    }
  }

  @Override
  public void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }

  @Override
  public void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }

  @Override
  public void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }
}

RequestManager从类名来看,应该就是请求管理类,它自身实现了LifecycleListener,在自身的构造方法中,和lifecycle进行了绑定,这样我们先前初始化的fragment的生命周期就在这里实现了监听,我们可以看下RequestManager生命周期方法中的一些代码,resumeRequests()pauseRequests(),顾名思义,他在执行相应生命周期的时候做了重新发送请求、暂停请求、销毁请求等操作。

到这里,我们就对glide的生命周期有了完整的了解,图片在加载时,会根据传入context对象的生命周期变化而做出暂停、销毁请求等操作,其中实现的主要原理就是glide生成了一个没有UI的Fragment同步context对象的生命周期,然后对这个自定义的Fragment进行监听,从而处理其他加载逻辑。

相关文章

网友评论

      本文标题:Glide源码解读(一)-- 图片加载的生命周期

      本文链接:https://www.haomeiwen.com/subject/cdgyxftx.html