美文网首页
Glide源码顺藤摸瓜之with和load主线

Glide源码顺藤摸瓜之with和load主线

作者: 天上飘的是浮云 | 来源:发表于2021-11-30 08:44 被阅读0次

前言:OKHttp和Retrofit都摸完了,今天咱们换换口味,顺藤摸一下Glide源码。Glide一听都是说源码太难看了,不是人看的。那咱们今天就解开它的神秘面纱,看看是不是人看的?O(∩_∩)O哈哈~

一、Glide浅谈

Glide相信大家都用过,因为太好用了。一句话总结就是:一行代码搞定,妈妈再也不用担心我的图片加载问题了。 \(^o^)/~

1. 当然了,每个框架必然有优点和缺点:
优点:
    1. 多样化媒体加载
    1. 生命周期集成
    1. 高效的缓存策略
    1. 内存开销小
缺点:
  • 虽然,Glide貌似一行代码可以搞定,但是真正要把它用活还是比较复杂的。
  • Glide功能强大,所以使用的方法非常多,源码也相对复杂,包较大
2. 我们撸源码的目的:
    1. 经常面试会问到,这是NO.1
    1. Glide是非常优秀的框架,我们可以学习它的设计思想
    1. 可以学习它使用无UIFragment来响应生命周期回调,这和Jetpack的思想是一致的。
    1. 框架源码看多了,很多架构的骨架会在你脑海里形成体系,当你自己去实现一个框架的时候,可以套用。
3. 我们要弄懂Glide的什么知识
4. 我们怎么撸Glide源码
        Glide.with(this)
            .load("https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=false")
            .into(imageView)

根据最简单的一句代码解决问题,我们有三条主线(只需要跟踪主线就够了,太深入反而把自己绕晕):

    1. Glide的with主线
    1. Glide的load主线
    1. Glide的into主线

二、Glide的with主线

根据上边的代码,使用Glide去加载图片,首先的使用:Glide.with()。我们来摸摸这条主线:

2.1 先说说这条主线的几个关键类:
    1. GlideBuilder: Glide的建造者类,复杂构建一个Glide实例,并添加各类默认线程池等。
    1. RequestManagerRetriever:它负责创建或从缓存中获取无UI的Fragment,与Activity绑定,实现生命周期方法监听。
    1. RequestManager:用来管理和start Glide请求的类。它根据绑定额生命周期的回调事件,自动的暂停、开始或者重启请求。
  @Override
  public synchronized void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }
    1. SupportRequestManagerFragment:继承至androidx.app.fragment.Fragment适配androidX的Fragment,它是一个无UI的Fragment,它与Activity进行绑定,实现生命周期的监听,并通知lifecycle,lifecycle在通知它的lifecycleListeners。
    1. RequestManagerFragment:继承至android.app.Fragment,它是一个无UI的Fragment,它与Activity进行绑定,实现生命周期的监听,并通知lifecycle,lifecycle在通知它的lifecycleListeners。
  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }
    1. ActivityFragmentLifecycle:它就是5/6中的默认lifecycle,实现生命周期方法的回调分发。
  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }
2.2 跟踪with主线
    1. 它总的来说是通过getRetriever(activity)获取了一个RequestManagerRetriever对象,然后通过它的get方法返回一个RequestManager对象
  public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }
    1. 跟踪 getRetriever(activity)方法发现,它是通过Glide实例的getRequestManagerRetriever()方法获取。
private static RequestManagerRetriever getRetriever(@Nullable Context context) {
    return Glide.get(context).getRequestManagerRetriever();
  }
    1. Glide.get(context)就是获取Glide实例了,它是单例模式,只会有一个Glide实例。
 public static Glide get(@NonNull Context context) {
    if (glide == null) {
      synchronized (Glide.class) {
        if (glide == null) {
          checkAndInitializeGlide(context, annotationGeneratedModule);
        }
      }
    }

    return glide;
  }

1. 一路跟踪下去,最终会来到
 private static void initializeGlide(
      @NonNull Context context,
      @NonNull GlideBuilder builder,
      @Nullable GeneratedAppGlideModule annotationGeneratedModule) {
      ...
      2. 通过建造者模式创建Glide实例
      Glide glide = builder.build(applicationContext);
     ...
      Glide.glide = glide;
}

3. 在GlideBuild.java的build方法中创建出Glide实例,并为其添加各种默认的线程池、
内存计算器、网络监听工厂、Bitmap缓存池、还有RequestListener默认回调、引擎Engine...
Glide build(@NonNull Context context) {
    if (diskCacheExecutor == null) {
      diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }
    ...
    if (engine == null) {
      engine =
          new Engine(
              memoryCache,
              ...r,
              isActiveResourceRetentionAllowed);
    }

4. 这时候RequestManagerRetriever实例就构建出来了
    RequestManagerRetriever requestManagerRetriever =
        new RequestManagerRetriever(requestManagerFactory);

    return new Glide(
        context,
        ...,
        isImageDecoderEnabledForBitmaps);
  }

    1. 这里在回到1.中的getRetriever(context).get(context);getRetriever(context)是返回一个RequestManagerRetriever对象,然后调用它的get()方法,这里我们进入到RequestManagerRetriever.get()方法中瞧瞧。
  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
          && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null) {
        return get(((ContextWrapper) context).getBaseContext());
      }
    }

    return getApplicationManager(context);
  }
    1. 这里根据传过来的Context类型进入到 不同的方法中,在分支get()方法中,它将创建或者获取缓存的无UI的Fragment与Actvitiy进行关联,实现生命周期的监听;到最后实际上归于两种Fragment类型:一种是androidx.fragment.app.fragment;一种是android.app.fragment;也就是为了适配不同版本。
    1. 我们这里就看一种get((Activity) context),其他都类似。

6.1 fragmentGet()方法会从获取的RequestManagerFragment 获取RequestManager对象。

6.2 如果RequestManager 对象为空的话,将通过factory.build创建。

6.3 factory默认为DEFAULT_FACTORY ,它新建了一个RequestManager对象。而传入的current.getGlideLifecycle(),则是ActivityFragmentLifecycle对象,他负责生命周期方法的分发。

6.4 将ActivityFragmentLifecycle传入RequestManager后,RequestManager本身就实现了LifecycleListener,它自己就是一个监听者。所以链条为Fragment.onStart() > ActivityFragmentLifecycle.onStart() > RequestManager.onStart()

1.  get((Activity) context)
 public RequestManager get(@NonNull Activity activity) {
   ...
      return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
  }

2. 
  private RequestManager fragmentGet( ...) {
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    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;
  }

3. 
  private static final RequestManagerFactory DEFAULT_FACTORY =
      new RequestManagerFactory() {
        @Override
        public RequestManager build(...) {
          return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);
        }
      };
    1. 这里回到6中的这句获取RequestManagerFragment对象的这句代码。

7.1 先从FragmentManager中通过tag获取。

7.2 没有话就在pendingRequestManagerFragments里获取:pendingRequestManagerFragments是一个HashMap,它保存RequestManagerFragment;而pendingSupportRequestManagerFragments保存SupportRequestManagerFragment。

7.3 前两步还没有找到的话,就新建一个。通过new RequestManagerFragment()方法创建,但是它默认会通过this(new ActivityFragmentLifecycle()); 将ActivityFragmentLifecycle作为默认lifeCycle传进去。

7.4 如果Activity可见的会调用lifeCycle.onStart()方法,并分发给lifeCycle的监听器。

7.5 将RequestManagerFragment缓存到Map中。

7.6 将RequestManagerFragment与Activity绑定起来。

7.7 然后通过Handler发送一个通知,将前一个不属于Activity的RequestManagerFragment移除。

 RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);

 private RequestManagerFragment getRequestManagerFragment(...) {
    7.1. 先从FragmentManager中通过tag获取
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    
   7.2. 没有话就在pendingRequestManagerFragments里获取pendingRequestManagerFragments
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        7.3. 前两步还没有找到的话,就新建一个
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        7.4. 如果Activity可见的会调用lifeCycle.onStart()方法,并分发给lifeCycle的监听器。
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        7.5. 将RequestManagerFragment缓存到Map中
        pendingRequestManagerFragments.put(fm, current);
        7.6. 将RequestManagerFragment与Activity绑定起来
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();

        7.7 然后通过Handler发送一个通知,将前一个不属于Activity的RequestManagerFragment移除
      handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }

    1. 跟踪到这,with主线我们也清晰了。在这条主线里主要是:
      首先:getRetriever()返回了一个RequestManagerRetriever对象,在这个过程中构建了Glide的单例对象,清晰了Glide通过GlideBuilder建造者模式创建,并初始化了很多线程池,缓存池等。
      然后:通过RequestManagerRetriever.get()方法返回一个RequestManager对象,在这个过程中Glide最重要的生命周期监听和绑定会呈现在我们面前,它通过构建一个无UI的Fragment与Activity进行绑定,那么当Activity有生命方法回调时,Fragment也会回调它的lifeCycle相对于的方法,在lifeCycle里就会将生命周期方法进行分发给他的监听器。而本身RequestManager实现了LifecycleListener接口,它就是一个生命周期的监听者。

三、Glide的load主线

load主线其实就是进入到RequestManager里的load方法中去了,其实它还有很多重载方法,支持各种参数如Bitmap、Drawable、String、Uri和File等,这也是Glide多样化体现之一。

val requestBuilder: RequestBuilder<Drawable> = requestManager.load("")
    1. 前面with主线返回的是一个RequestManager实例,load主线就是通过RequestManagert.load()方法返回了一个RequestBuilder对象。
    1. 它的源码还是比较简单,asDrawable()实则新建了一个RequestBuilder对象。然后调用了RequestBuilder.load()方法将Uri传入并赋值给model。
  public RequestBuilder<Drawable> load(@Nullable String string) {
    return asDrawable().load(string);
  }

  public RequestBuilder<Drawable> asDrawable() {
    return as(Drawable.class);
  }

  public <ResourceType> RequestBuilder<ResourceType> as(
      @NonNull Class<ResourceType> resourceClass) {
    return new RequestBuilder<>(glide, this, resourceClass, context);
  }

  public RequestBuilder<TranscodeType> load(@Nullable String string) {
    return loadGeneric(string);
  }

 private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    isModelSet = true;
    return this;
  }

四、Glide的into主线

这条主线才Glide的重中之重:在这条主线里包括了Glide的核心功能:切换子线程去请求数据、它的缓存处理机制以及获取图片的stream后,切换为主线程转为为对应的格式交由ImageView显示。

由于篇幅问题,这里又是重中之重,再加上我也是读者,发现文章太长其实挺恶心的,读起来费时费力。所以我们另起一文聊聊,

相关文章

网友评论

      本文标题:Glide源码顺藤摸瓜之with和load主线

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