Glide 怎么绑定页面的生命周期的?

文章目录

  • 前言
  • 简要说明过程
  • 怎么完成绑定
  • 核心类的作用
  • 总结

前言
Glide 是非常强大的图片加载框架,基本在所有的面试中都会被问到,而问得最多的可能就是如何与页面生命周期的绑定,针对这点,我做了一下整理,我自己也开了一个项目,关于Android的面试题,有需要的可以进来看看https://github.com/shenshizhong/AndroidIQ

简单说明过程
对整个过程有个大体的印象,不然看着源码就找不着北了。
绑定的大体过程:Glide -> RequestManagerRetriever -> RequestManagerFragment
-> ActivityFragmentLifecycle -> RequestManager -> RequestTracker

怎么完成绑定
这是最关键的,这里我们主要是以Activity 为过程,来了解绑定,其他的可以以此类推。
首先我们我们从最熟悉的使用开始 Glide.with(imageView.getContext())

Glide
  public RequestManager get(@NonNull Context context) {
    if (context == null) {
      throw new IllegalArgumentException("You cannot start a load on a null Context");
    } else if (Util.isOnMainThread() && !(context instanceof Application)) {
      if (context instanceof FragmentActivity) {
        return get((FragmentActivity) context);
      } else if (context instanceof Activity) {    // 这是我们要分析的,其他差不多,以此类推
        return get((Activity) context);
      } else if (context instanceof ContextWrapper) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }
    return getApplicationManager(context);
  }

接着进入get方法中查看

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

public RequestManager get(@NonNull Activity activity) {
//判断是不是在后台运行,如果是的话,使用整个应用为生命周期
 if (Util.isOnBackgroundThread()) {
   return get(activity.getApplicationContext());
 } else {
   assertNotDestroyed(activity);
   android.app.FragmentManager fm = activity.getFragmentManager();
   return fragmentGet(
       activity, fm, /*parentHint=*/ null, isActivityVisible(activity));    //这是我们要看的
 }
}

这里我们只要是看页面的生命周期,所以我们看fragmentGet 里面的内容

RequestManagerRetriever # fragmentGet
private RequestManager fragmentGet(@NonNull Context context,
    @NonNull android.app.FragmentManager fm,
    @Nullable android.app.Fragment parentHint,
    boolean isParentVisible) {
    //创建一个空的 Fragment 对象,主要用来监听页面的生命周期
  RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
  RequestManager requestManager = current.getRequestManager();  //创建一个 RequestManager 对象
  if (requestManager == null) {
    // TODO(b/27524013): Factor out this Glide.get() call.
    Glide glide = Glide.get(context);
    requestManager =
        factory.build(
            glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);//将 Fragment 的生命周期传递给 RequestManager
    current.setRequestManager(requestManager);   //将RequestManager 传递给 Fragment
  }
  return requestManager;
}


private RequestManagerFragment getRequestManagerFragment(@NonNull final android.app.FragmentManager fm, @Nullable android.app.Fragment parentHint,boolean isParentVisible) {
  RequestManagerFragment current = (RequestManagerFragment)fm.findFragmentByTag(FRAGMENT_TAG);
  if (current == null) {
    current = pendingRequestManagerFragments.get(fm);
    if (current == null) {
      current = new RequestManagerFragment();     //可以看出,所要创建的Fragment 的实现类是RequestManagerFragment
      current.setParentFragmentHint(parentHint);
      if (isParentVisible) {
        current.getGlideLifecycle().onStart();
      }
      pendingRequestManagerFragments.put(fm, current);
      fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
      handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
    }
  }
  return current;
}

这里主要是创建一个空的Fragment 和 RequestManager 对象,然后将 Fragment 的生命周期传递给 RequestManager,把RequestManager 传递给 Fragment。

到这里主要完成的事情:通过RequestManagerRetriever 将Fragment 和 RequestManager联系起来了。下面就具体说下,怎么绑定了。

------------具体绑定过程----------

首先从新建的空Fragment说起,它的具体实现类是RequestManagerFragment,在创建的时候,同时创建了ActivityFragmentLifecycle

RequestManagerFragment
public RequestManagerFragment() {
 this(new ActivityFragmentLifecycle());
}

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

以下就是关键代码了,这里头会在生命周期中,调用ActivityFragmentLifecycle的相应方法。

RequestManagerFragment

  @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的几个关键方法

public void addListener(@NonNull LifecycleListener listener) {
    lifecycleListeners.add(listener);
    if (isDestroyed) {
      listener.onDestroy();
    } else if (isStarted) {
      listener.onStart();
    } else {
      listener.onStop();
    }
  }

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();
    }
  }

从上面的代码中,我们看到调用了 lifecycleListener 的相应方法,那么这个lifecycleListener 实现类是谁呢?我们看到 lifecycleListener.onStart(); 这个 lifecycleListener 其实是从lifecycleListeners 的容器中拿出来的,那lifecycleListeners 又是在addListener 进行添加的。
这个时候我们想知道,addListener 被谁调用了,点方法可以看到调用的类(AS提供的),我们发现是RequestManager,是的,我们看到了如下的代码:

public class RequestManager implements LifecycleListener,ModelTypes<RequestBuilder<Drawable>> {
...
  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
            ···
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);      //这里添加了
    }
    lifecycle.addListener(connectivityMonitor);

    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

    glide.registerRequestManager(this);
  }

这个时候我们回想下之前看过的代码,其实我们在创建requestManager对象的时候, current.getGlideLifecycle() 已经把fragment 中的 ActivityFragmentLifecycle 传进去了。代码如下:

RequestManagerRetriever # fragmentGet
requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);

好了,我们清楚了,ActivityFragmentLifecycle 的方法会调用RequestManager 的方法,比如上面的 lifecycleListener.onStart();其实调用的就是RequestManager #onStart。那么我们看下RequestManager的类:

RequestManager
  public void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }
  public void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }
  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);
  }

我们就看onStart 吧,其他方法类推,他会调用pauseRequests(); 看下里头做了什么?

RequestManager
public void resumeRequests() {
    Util.assertMainThread();
    requestTracker.resumeRequests();
  }

继续点 requestTracker.resumeRequests(); 我们看到了下面的代码

RequestTracker
public void resumeRequests() {
    isPaused = false;
    for (Request request : Util.getSnapshot(requests)) {
      if (!request.isComplete() && !request.isRunning()) {
        request.begin();   //这就是请求的开始
      }
    }
    pendingRequests.clear();
  }

request.begin(); 是进行请求的,也就是我们glide 进行的操作。到这里,就完成了生命周期开始的绑定,然后看其他的方法,比如onStop(),onDestroy(),其实就是执行Glide的停止和结束的操作了。这个绑定的过程就是如此了,看完是不是舒畅了一下呢。

核心类的作用

  • RequestManagerFragment:实现一个无UI的fragment。
  • ActivityFragmentLifecycle:无UI的fragment通过它,去调用RequestManager
  • RequestManager:实现关键的几个方法,去调用glide 的操作
  • RequestManagerRetriever:作为一个桥梁,将RequestManagerFragment
    和RequestManager给联系起来

总结:
总体的过程就是,空RequestManagerFragment 的生命周期调用 ActivityFragmentLifecycle,然后ActivityFragmentLifecycle 调用 RequestManager ,RequestManager 再去调用RequestTracker 的glide操作,最终实现gilde的操作,能够根据页面的生命周期做相应的处理。

如果对你有一点点帮助,那是值得高兴的事情。:)

我的csdn:http://blog.csdn.net/shenshizhong
我的简书:http://www.jianshu.com/u/345daf0211ad

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值