Glide加载流程分析

本文主要分析了Glide图片加载的流程,包括with()、load()和into()方法的使用。通过对Glide源码的阅读,揭示了RequestManager、RequestBuilder在图片加载过程中的作用,以及如何根据上下文创建对应的RequestManager。还简单介绍了图片加载的资源来源,包括活动资源、内存缓存和文件加载。最后对Glide的生命周期绑定和缓存机制提出了疑问,为后续深入研究埋下伏笔。
摘要由CSDN通过智能技术生成

再开始写文章之前非常感谢这篇博客的作者。是他的这篇文章给了我glide源码阅读的一些灵感。在这之前几次阅读都没有搞明白的glide加载流程在阅读了他的这篇文章后参考类似的方法对glide的源码结构有了一个比较清晰的认识。下面是他的这篇文章的地址:

https://blog.csdn.net/carson_ho/article/details/79212841

 

前言

glide是我们项目开发中非常常见的一个三方框架,它的功能极其强大它为我们出来好了图片的加载缓存等功能。使用起来非常方便。那么我们应该如何来进行使用呢?它的实现原来又是什么呢?

Glide地址: https://github.com/bumptech/glide

Glide官方使用文档: https://muyangmin.github.io/glide-docs-cn/doc/options.html

文章glide的使用版本:4.9.0

 

本篇文章主要对glide的加载流程进行分析。

 

基本使用

  1. 简单的加载

    //context可以使activity,application,fragment
    //imageUrl为图片地址
    //image 需要显示的图片
    Glide.with(context).load(imageUrl).into(image);
  2. 设置占位图以及加载出错的图片

    Glide.with(context)
    .load(imageUrl)
    .placeholder(R.drawable.coordinator_demo)
    .error(R.drawable.coordinator_demo)
    .into(image);

    上面是我们为单个图片的加载设置配置,但是常见的的情况下我们许多图片的加载除了加载地址和需要显示的ImageView不同其他的都是相同的。难道我们要为每一个图片的加载都进行设置吗?答案是否定的,glide为我们提供了一个对象:RequestOptions方便我们共享不同模块的图片加载项。

    val requestOptions = RequestOptions()
                requestOptions
                        .placeholder(R.drawable.coordinator_demo)
                        .error(R.drawable.coordinator_demo)
     Glide.with(context).load(imageUrl).apply(requestOptions).into(image);

    RequestOptions对象的创建非常简单,可以直接new一个对象或者通过它的任意一个静态方法的调用返回RequestOptions对象。

Glide源码分析

通过给glide的使用我们发现Glide的图片加载主要使用了三个方法:

  • with()

  • load()

  • into()

with方法

 

可以看到抛开废弃的方法Glide有5个重载的with.它们的返回对象都是RequestManager对象的实例。

通过阅读源码我们发现最终返回的RequestManager对象是由RequestManagerRetriever的get方法返回的。get()有5个重载方法分别对应Glide的5个重载。我们来一个一个进行分析。

  1. 传递的Context是Application的context.最终调用的是getApplicationManager方法。其实现如下:

    @NonNull
      private RequestManager getApplicationManager(@NonNull Context context) {
        // Either an application context or we're on a background thread.
        if (applicationManager == null) {
          synchronized (this) {
            if (applicationManager == null) {
              // Normally pause/resume is taken care of by the fragment we add to the fragment or
              // activity. However, in this case since the manager attached to the application will not
              // receive lifecycle events, we must force the manager to start resumed using
              // ApplicationLifecycle.
    ​
              // TODO(b/27524013): Factor out this Glide.get() call.
              Glide glide = Glide.get(context.getApplicationContext());
              applicationManager =
                  factory.build(
                      glide,
                      new ApplicationLifecycle(),
                      new EmptyRequestManagerTreeNode(),
                      context.getApplicationContext());
            }
          }
        }
    ​
        return applicationManager;
      }

    这里通过双重锁的单例来保证针对Application的Context只有一个RequestManager.

  2. 传入对象是FragmentActivity

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

    可以看到上面的代码最终会调用到supportFragmentGet方法,这里才是真正返回RequestManager的位置。

    @NonNull
      private RequestManager supportFragmentGet(
          @NonNull Context context,
          @NonNull FragmentManager fm,
          @Nullable Fragment parentHint,
          boolean isParentVisible) {
        SupportRequestManagerFragment current =
            getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
        RequestManager requestManager = current.getRequestManager();
        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);
          current.setRequestManager(requestManager);
        }
        return requestManager;
      }

    因为这篇文章知识粗略的了解Glide的加载我们先不去深入分析这个RequestManager是如何生成的。

  3. 传入对象是Fragment

    @NonNull
      public RequestManager get(@NonNull Fragment fragment) {
        Preconditions.checkNotNull(fragment.getActivity(),
              "You cannot start a load on a fragment before it is attached or after it is destroyed");
        if (Util.isOnBackgroundThread()) {
          return get(fragment.getActivity().getApplicationContext());
        } else {
          FragmentManager fm = fragment.getChildFragmentManager();
          return supportFragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
        }
      }

    同样的这里也是调用的supportFragmentGet来获取RequestManager对象。

    这里我们不需要太过关注细节只需要知道Glide会根据传入的不同的activity或者Fragment来创建对应的requestManager。并与其生命周期进行绑定

load

Glide的with方法返回的是RequestManager接着我们看看RequestManager的load方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值