Glide 浅析(上)

Glide 是一个世界级的图片加载框架,可以说现在没有哪一个图片加载框架超越了 Glide。探寻 Glide 的源码,对于我们能够更好地使用 Glide 以及了解如何构建一个高性能、高安全性的图片加载框架有着极大的帮助。

使用过 Glide 的开发者都知道,当我们加载图片的时候,只需要 Glide.wtih(context).load(url).into(imageView) 这一句代码就可以了。但是在 Glide 代码内部为了实现这句代码的功能,进行了很多代码处理。

接下来我就以这句代码中的三个函数分为三个部分探寻 Glide 的源码。

(以下分析的是 Glide 4.11 的源码)

wtih(context)

我们知道图片加载通常是异步的,因为这是耗时操作,不能在 UI 线程中执行。正是因为需要异步执行,所以监听 UI 的生命周期显得尤为重要。

Glide 通过 Glide#with 函数传入的 context 来实现监听 UI 的生命周期。

根据传入的 Context 类型 Glide#with 分为几个重载函数。

// Glide.java
@NonNull
public static RequestManager with(@NonNull Context context)
{
    return getRetriever(context).get(context);
}

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

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

@NonNull
public static RequestManager with(@NonNull Fragment fragment)
{
    return getRetriever(fragment.getContext()).get(fragment);
}

@Deprecated
@NonNull
public static RequestManager with(@NonNull android.app.Fragment fragment)
{
    return getRetriever(fragment.getActivity()).get(fragment);
}

@NonNull
public static RequestManager with(@NonNull View view)
{
    return getRetriever(view.getContext()).get(view);
}
复制代码

我们先来看 Glide#getRetriever 函数。

// Glide.java
@NonNull
private static RequestManagerRetriever getRetriever(@Nullable Context context)
{
    ......
    return Glide.get(context).getRequestManagerRetriever();
}

private static volatile Glide glide;

@NonNull
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;
}

@GuardedBy("Glide.class")
private static void checkAndInitializeGlide(
        @NonNull Context context, 
        @Nullable GeneratedAppGlideModule generatedAppGlideModule
){
    // isInitializing 标志着 Glide 是否处于初始化中,这里会检查 Glide 是否处于初始化中
    if (isInitializing)
    {
      throw new IllegalStateException(
          "You cannot call Glide.get() in registerComponents(),"
              + " use the provided Glide instance instead");
    }
    // 修改标志,表示 Glide 正处于初始化中
    isInitializing = true;
    // 开始进行 Glide 初始化
    initializeGlide(context, generatedAppGlideModule);
    isInitializing = false;
}

@GuardedBy("Glide.class")
private static void initializeGlide(
        @NonNull Context context, 
        @Nullable GeneratedAppGlideModule generatedAppGlideModule
){
    // 创建一个 GlideBuilder 再进行初始化(建造者模式)
    initializeGlide(context, new GlideBuilder(), generatedAppGlideModule);
}

@GuardedBy("Glide.class")
@SuppressWarnings("deprecation")
private static void initializeGlide(
        @NonNull Context context,
        @NonNull GlideBuilder builder,
        @Nullable GeneratedAppGlideModule annotationGeneratedModule
){
    // 拿到 application 的 context,这样可以避免内存泄漏
    Context applicationContext = context.getApplicationContext();
    ......
    // 通过 GlideBuilder 建造者模式,构建出 Glide 对象
    Glide glide = builder.build(applicationContext);
    ......
    // 将构建出来的 Glide 对象赋值给静态变量 glide
    Glide.glide = glide;
}

// GlideBuilder.java

// 管理线程池
private Engine engine;

// 对象池(享元模式),这样做避免重复创建对象,对内存开销有一定效果
private BitmapPool bitmapPool;
private ArrayPool arrayPool;

// GlideExecutor 线程池
private GlideExecutor sourceExecutor;
private GlideExecutor diskCacheExecutor;

// 本地磁盘缓存
private DiskCache.Factory diskCacheFactory;

// 内存缓存
private MemoryCache memoryCache;
private MemorySizeCalculator memorySizeCalculator;

// 网络连接监听
private ConnectivityMonitorFactory connectivityMonitorFactory;

@NonNull
Glide build(@NonNull Context context)
{
    if (sourceExecutor == null)
    {
        // 创建一个用于网络请求的线程池
        sourceExecutor = GlideExecutor.newSourceExecutor();
    }
    if (diskCacheExecutor == null)
    {
        // 创建一个用于本地磁盘缓存的线程池
        diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();
    }
    if (animationExecutor == null)
    {
        // 创建一个用于加载图片动画的线程池
        animationExecutor = GlideExecutor.newAnimationExecutor();
    }
    if (memorySizeCalculator == null)
    {
        // 创建一个用于图片加载到内存的计算器
        memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();
    }
    if (connectivityMonitorFactory == null)
    {
        // 创建一个监控网络连接的工厂类(默认)
        connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

    // 创建一个 Bitmap 对象池
    if (bitmapPool == null)
    {
        int size = memorySizeCalculator.getBitmapPoolSize();
        // 如果池子里还有可用的,直接加入最近最少使用的 LruBitmapPool 容器里
        if (size > 0)
        {
            bitmapPool = new LruBitmapPool(size);
        }
        else // 如果池子已经满了,那么就装在 BitmapPoolAdapter
        {
            bitmapPool = new BitmapPoolAdapter();
        }
    }

    if (arrayPool == null)
    {
        // 创建一个数组对象池
        arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());
    }
    if (memoryCache == null)
    {
        // 创建资源内存缓存
        memoryCache = new LruResourceCache(memorySizeCalculator.getMemoryCacheSize());
    }
    if (diskCacheFactory == null)
    {
        // 创建磁盘缓存的工厂类
        diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }
    if (engine == null)
    {
        // 创建执行缓存策略和线程池的引擎
        engine = new Engine(
                memoryCache,
                diskCacheFactory,
                diskCacheExecutor,
                sourceExecutor,
                GlideExecutor.newUnlimitedSourceExecutor(),
                animationExecutor,
                isActiveResourceRetentionAllowed);
    }
    if (defaultRequestListeners == null)
    {
        defaultRequestListeners = Collections.emptyList();
    }
    else
    {
        defaultRequestListeners = Collections.unmodifiableList(defaultRequestListeners);
    }

    // 创建 RequestManagerRetriever
    RequestManagerRetriever requestManagerRetriever = 
            new RequestManagerRetriever(requestManagerFactory);

    // 传入参数构建 Glide
    return new Glide(
            context,
            engine,
            memoryCache,
            bitmapPool,
            arrayPool,
            requestManagerRetriever,
            connectivityMonitorFactory,
            logLevel,
            defaultRequestOptionsFactory,
            defaultTransitionOptions,
            defaultRequestListeners,
            isLoggingRequestOriginsEnabled,
            isImageDecoderEnabledForBitmaps);
}

// Glide.java
Glide(
      @NonNull Context context,
      @NonNull Engine engine,
      @NonNull MemoryCache memoryCache,
      @NonNull BitmapPool bitmapPool,
      @NonNull ArrayPool arrayPool,
      @NonNull RequestManagerRetriever requestManagerRetriever,
      @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
      int logLevel,
      @NonNull RequestOptionsFactory defaultRequestOptionsFactory,
      @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
      @NonNull List<RequestListener<Object>> defaultRequestListeners,
      boolean isLoggingRequestOriginsEnabled,
      boolean isImageDecoderEnabledForBitmaps
){
    // 将 GlideBuilder 构建的线程池、对象池、缓存池保存到 Glide 中
    this.engine = engine;
    this.bitmapPool = bitmapPool;
    this.arrayPool = arrayPool;
    this.memoryCache = memoryCache;
    this.requestManagerRetriever = requestManagerRetriever;
    this.connectivityMonitorFactory = connectivityMonitorFactory;
    this.defaultRequestOptionsFactory = defaultRequestOptionsFactory;
    ......
    // 用于显示对应图片的工厂
    ImageViewTargetFactory imageViewTargetFactory = new ImageViewTargetFactory();
    
    // 创建 Glide 专属的 context(glideContext)
    glideContext = new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptionsFactory,
            defaultTransitionOptions,
            defaultRequestListeners,
            engine,
            isLoggingRequestOriginsEnabled,
            logLevel);
}

@NonNull
public RequestManagerRetriever getRequestManagerRetriever()
{
    return requestManagerRetriever;
}
复制代码

在 Glide 初始化的过程中,会把线程池、对象池、缓存池、RequestManagerRetriever 都创建出来,并构建了 GlideContext。

最终 Glide#getRetriever 函数会返回 Glide 单例对象中的 requestManagerRetriever 字段。

我们接着来看 RequestManagerRetriever#get 函数。

根据传入的 Context 类型 RequestManagerRetriever#get 分为几个重载函数。

// RequestManagerRetriever.java
@NonNull
public RequestManager get(@NonNull Context context)
{
    ......
    // Util.isOnMainThread():根据线程对应的 looper 对象判断当前调用线程是否为主线程
    // 如果 当前线程是主线程 且 context 的类型不是 Application
    else if (Util.isOnMainThread() && !(context instanceof Application))
    {
        // 如果 context 的类型是 FragmentActivity
        if (context instanceof FragmentActivity)
        {
            // 执行 get(FragmentActivity activity) 函数
            return get((FragmentActivity) context);
        }
        // 如果 context 的类型是 Activity
        else if (context instanceof Activity)
        {
            // 执行 get(Activity activity) 函数
            return get((Activity) context);
        }
        else if (context instanceof ContextWrapper 
                && ((ContextWrapper) context).getBaseContext().getApplicationContext() != null)
        {
            // 递归执行 get(Context context),直到匹配到合适的 context 类型
            return get(((ContextWrapper) context).getBaseContext());
        }
    }
    // 如果 当前线程是子线程 或 context 的类型是 Application
    return getApplicationManager(context);
}

@NonNull
public RequestManager get(@NonNull FragmentActivity activity)
{
    // 如果当前线程是子线程
    if (Util.isOnBackgroundThread())
    {
        // 执行 get(Context context) 函数,并传入 application 的 context
        return get(activity.getApplicationContext());
    }
    else // 如果当前线程是主线程
    {
        ......
        FragmentManager fm = activity.getSupportFragmentManager();
        return supportFragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
}

@NonNull
public RequestManager get(@NonNull Fragment fragment)
{
    ......
    // 如果当前线程是子线程
    if (Util.isOnBackgroundThread())
    {
        // 执行 get(Context context) 函数,并传入 application 的 context
        return get(fragment.getContext().getApplicationContext());
    }
    else // 如果当前线程是主线程
    {
        FragmentManager fm = fragment.getChildFragmentManager();
        return supportFragmentGet(fragment.getContext(), fm, fragment, fragment.isVisible());
    }
}

@NonNull
public RequestManager get(@NonNull Activity activity)
{
    // 如果当前线程是子线程
    if (Util.isOnBackgroundThread())
    {
        // 执行 get(Context context) 函数,并传入 application 的 context
        return get(activity.getApplicationContext());
    }
    else // 如果当前线程是主线程
    {
        ......
        android.app.FragmentManager fm = activity.getFragmentManager();
        return fragmentGet(activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
}

@NonNull
public RequestManager get(@NonNull View view)
{
    // 如果当前线程是子线程
    if (Util.isOnBackgroundThread())
    {
        // 执行 get(Context context) 函数,并传入 application 的 context
        return get(view.getContext().getApplicationContext());
    }
    ......
    // 递归查找 view 所在的 activity
    Activity activity = findActivity(view.getContext());
    // 如果 view 不在 activity 中
    if (activity == null)
    {
        // 执行 get(Context context) 函数,并传入 application 的 context
        return get(view.getContext().getApplicationContext());
    }
    // 如果 view 所在的 activity 是 FragmentActivity
    if (activity instanceof FragmentActivity)
    {
        // 查找 view 是否存在于 fragment(AndroidX)中,并返回 view 所在的 fragment(AndroidX)
        Fragment fragment = findSupportFragment(view, (FragmentActivity) activity);
        // 如果 view 存在于 fragment(AndroidX)中,则执行 get(Fragment fragment) 函数;
        // 否则执行 get(FragmentActivity activity) 函数
        return fragment != null ? get(fragment) : get((FragmentActivity) activity);
    }

    // 查找 view 是否存在于 fragment(android.app)中,并返回 view 所在的 fragment(android.app)
    android.app.Fragment fragment = findFragment(view, activity);
    // 如果 view 不存在于 fragment(android.app)中
    if (fragment == null)
    {
        // 执行 get(Activity activity) 函数
        return get(activity);
    }
    // 如果 view 存在于 fragment(android.app)中,执行 
    return get(fragment);
}

@Deprecated
@NonNull
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public RequestManager get(@NonNull android.app.Fragment fragment)
{
    ......
    // 如果 当前线程是子线程 或 运行的手机系统低于 Android 4.2
    if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
    {
        // 执行 get(Context context) 函数,并传入 application 的 context
        return get(fragment.getActivity().getApplicationContext());
    }
    else
    {
        android.app.FragmentManager fm = fragment.getChildFragmentManager();
        return fragmentGet(fragment.getActivity(), fm, fragment, fragment.isVisible());
    }
}
复制代码

我们可以通过一张表格来总结一下

主线程 子线程
Context 判断 Context 的类型 执行 getApplicationManager 函数
Activity 执行 fragmentGet 函数 执行 getApplicationManager 函数
FragmentActivity 执行 supportFragmentGet 函数 执行 getApplicationManager 函数
Fragment(AndroidX) 执行 supportFragmentGet 函数 执行 getApplicationManager 函数
Fragment(android.app) 执行 fragmentGet 函数 执行 getApplicationManager 函数
View 判断 view 所在的组件是 AndroidX / android.app,执行对应的 supportFragmentGet / fragmentGet 函数 执行 getApplicationManager 函数

我们看到当运行线程是子线程时,都是调用的 RequestManagerRetriever#getApplicationManager 函数。那我们就先来看 RequestManagerRetriever#getApplicationManager 函数。

// RequestManagerRetriever.java
@NonNull
private RequestManager getApplicationManager(@NonNull Context context)
{
    // 单例模式
    if (applicationManager == null)
    {
        synchronized (this)
        {
            if (applicationManager == null)
            {
                Glide glide = Glide.get(context.getApplicationContext());
                // 创建 RequestManager
                applicationManager = factory.build(glide, 
                        new ApplicationLifecycle(), 
                        new EmptyRequestManagerTreeNode(), 
                        context.getApplicationContext());
            }
        }
    }
    return applicationManager;
}

// RequestManager.java
RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context
){
    ......
    // 此时 lifecycle = ApplicationLifecycle
    this.lifecycle = lifecycle;
    ......
    // 如果当前线程是子线程
    if (Util.isOnBackgroundThread())
    {
        // 利用 Handler 切换线程执行 Runnable
        mainHandler.post(addSelfToLifecycle);
    }
    else
    {
        // 在 ApplicationLifecycle 中添加监听(this)
        lifecycle.addListener(this);
    }
    // 在 ApplicationLifecycle 中添加监听(网络连接)
    lifecycle.addListener(connectivityMonitor);
    ......
}

private final Runnable addSelfToLifecycle = new Runnable()
{
    @Override
    public void run()
    {
        // 在 ApplicationLifecycle 中添加监听(this)
        lifecycle.addListener(RequestManager.this);
    }
};

// ApplicationLifecycle.java
class ApplicationLifecycle implements Lifecycle
{
    @Override
    public void addListener(@NonNull LifecycleListener listener)
    {
        // 此时 application 已经启动了,直接回调 onStart 函数
        listener.onStart();
    }

    @Override
    public void removeListener(@NonNull LifecycleListener listener)
    {
        // 当 application 结束的时候,整个 app 进程的内存都会被回收,不需要做任何事
    }
}
复制代码

RequestManagerRetriever#getApplicationManager 函数中使用单例模式创建了一个对应着 application 生命周期的 RequestManager。

ApplicationLifecycle 代表着 application 的生命周期回调。但是实际上 application 的生命周期无法被监听,所以 ApplicationLifecycle 这个类并没有什么实际的意义。

我们接着来看 RequestManagerRetriever#supportFragmentGet 函数。

// RequestManagerRetriever.java
@NonNull
private RequestManager supportFragmentGet(
        @NonNull Context context,
        @NonNull FragmentManager fm,
        @Nullable Fragment parentHint,
        boolean isParentVisible
){
    // 从 FragmentManager 中获取空白的 SupportRequestManagerFragment
    SupportRequestManagerFragment current =
            getSupportRequestManagerFragment(fm, parentHint, isParentVisible);
    // 从 SupportRequestManagerFragment 中获取 RequestManager
    RequestManager requestManager = current.getRequestManager();
    // 如果 SupportRequestManagerFragment 中没有 RequestManager
    if (requestManager == null)
    {
        Glide glide = Glide.get(context);
        // 创建 RequestManager
        requestManager = factory.build(
                glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
        // 将 RequestManager 设置入 SupportRequestManagerFragment
        current.setRequestManager(requestManager);
    }
    return requestManager;
}

static final String FRAGMENT_TAG = "com.bumptech.glide.manager";

final Map<FragmentManager, SupportRequestManagerFragment> pendingSupportRequestManagerFragments 
        = new HashMap<>();

@NonNull
private SupportRequestManagerFragment getSupportRequestManagerFragment(
        @NonNull final FragmentManager fm, 
        @Nullable Fragment parentHint, 
        boolean isParentVisible
){
    // 通过 Tag 标签在 FragmentManager 中寻找是否存在这个空白 fragment
    SupportRequestManagerFragment current =
            (SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    // 如果这个空白 fragment 在 FragmentManager 中不存在
    if (current == null)
    {
        // 在 Map 缓存中寻找这个空白 fragment 是否存在
        current = pendingSupportRequestManagerFragments.get(fm);
        // 如果这个空白 fragment 在 Map 缓存中也不存在
        if (current == null)
        {
            // 创建 SupportRequestManagerFragment
            current = new SupportRequestManagerFragment();
            ......
            // 将这个空白 fragment 放入 Map 缓存中
            pendingSupportRequestManagerFragments.put(fm, current);
            // 给 FragmentManager 提交事务
            fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
            // 给主线程 Handler 添加消息
            handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
        }
    }
    return current;
}

@Override
public boolean handleMessage(Message message)
{
    switch (message.what)
    {
        ......
        case ID_REMOVE_SUPPORT_FRAGMENT_MANAGER:
            FragmentManager supportFm = (FragmentManager) message.obj;
            // 删除 Map 缓存中对应的记录
            pendingSupportRequestManagerFragments.remove(supportFm);
            break;
        ......
    }
    return false;
}

// SupportRequestManagerFragment.java
private final ActivityFragmentLifecycle lifecycle;

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

public SupportRequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle)
{
    this.lifecycle = lifecycle;
}

@NonNull
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();
}
复制代码

RequestManagerRetriever#supportFragmentGet 函数中,通过 fragment 事务添加了一个空白的 fragment 用于监听 UI 的生命周期,并在这个 fragment 中保存了对应着这个 fragment 生命周期的 RequestManager 对象。

我们知道通过 fragment 事务添加 fragment 不是立刻生效的,因为 fragment 事务的底层原理是通过 Handler 来实现的。

因此在 RequestManagerRetriever#getSupportRequestManagerFragment 函数中,通过一个 Map 缓存实现了避免事务的重复提交而导致 fragment 重复创建。

ActivityFragmentLifecycle 代表着空白 fragment 的生命周期回调。在 fragment 的生命周期中会回调 ActivityFragmentLifecycle 中对应的方法。

class ActivityFragmentLifecycle implements Lifecycle
{
    private final Set<LifecycleListener> lifecycleListeners = 
            Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
    // 记录当前空白 fragment 是否经过了 onStart
    private boolean isStarted;
    // 记录当前空白 fragment 是否经过了 onDestroy
    private boolean isDestroyed;

    @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()
    {
        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();
        }
    }
}
复制代码

在 ActivityFragmentLifecycle 中使用了一个 Set 集合来保存所有注册过的 LifecycleListener。当空白 fragment 的生命周期发生对应变化时,就会遍历 Set 集合回调 LifecycleListener 中对应的函数。

当空白 fragment 的生命周期发生变化时,就会回调 RequestManager 中对应的函数。

// RequestManager.java

@GuardedBy("this")
private final TargetTracker targetTracker = new TargetTracker();

@Override
public synchronized void onStart()
{
    resumeRequests();
    // 回调 TargetTracker.onStart 函数
    targetTracker.onStart();
}

@Override
public synchronized void onStop()
{
    pauseRequests();
    // 回调 TargetTracker.onStop 函数
    targetTracker.onStop();
}

@Override
public synchronized void onDestroy()
{
    // 回调 TargetTracker.onDestroy 函数
    targetTracker.onDestroy();
    ......
    // 移除 Lifecycle 中的注册过的监听
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    ......
}
复制代码

在 Glide 中如果一个类想要监听生命周期,那么这个类可以这么做:

  • 将自己注册入 Lifecycle
  • 在 RequestManager 对应生命周期的函数中回调自己的函数

RequestManagerRetriever#fragmentGet 函数的流程与 RequestManagerRetriever#supportFragmentGet 函数是一样的。只不过 RequestManagerRetriever#fragmentGet 函数生成的空白 fragment 的类型是 android.app 的,RequestManagerRetriever#supportFragmentGet 函数生成的空白 fragment 的类型是 AndroidX 的。

我们可以用一张图来总结一下 Glide#with 函数的流程:

未命名文件.png

Glide.with(context) 主要做了线程池 + 缓存 + 请求管理与生命周期绑定 + 其它配置初始化的构建。

load(url)

我们知道了 Glide#with 函数会返回一个监听了生命周期的 RequestManager 对象。

接着来看 RequestManager#load 函数。

根据传入的参数类型 RequestManager#load 分为几个重载函数。在这里只分析 load(String) 这一类型,别的类型也是一样的。

// RequestManager.java
public RequestBuilder<Drawable> load(@Nullable String string)
{
    return asDrawable().load(string);
}

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

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

// RequestBuilder.java
@NonNull
@Override
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable String string)
{
    return loadGeneric(string);
}

// 描述加载的数据源,这个就是我们传入的网址(http://xxxx.png)
@Nullable private Object model;
// 描述这个请求是否已经添加了加载的数据源
private boolean isModelSet;

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

Glide.load(url) 主要做了构建 RequestBuilder + 将我们输入的 URL(RequestBuilder.model)设置入 RequestBuilder。

into(imageView)

我们知道了 Glide#load 函数会返回一个 RequestBuilder 对象。

接着来看 RequestBuilder#into 函数。

// RequestBuilder.java
@NonNull
public ViewTarget<ImageView, TranscodeType> into(@NonNull ImageView view)
{
    ......
    BaseRequestOptions<?> requestOptions = this;
    if (!requestOptions.isTransformationSet()
            && requestOptions.isTransformationAllowed()
            && view.getScaleType() != null)
    {
        // 根据 ImageView 的 ScaleType 属性来重构 RequestOptions
        switch (view.getScaleType())
        {
            ......
            case FIT_CENTER: // 默认值
            case FIT_START:
            case FIT_END:
                // 这里使用了克隆(原型设计模式)
                requestOptions = requestOptions.clone().optionalFitCenter();
                break;
            ......
        }
    }
    
    return into(
        glideContext.buildImageViewTarget(view, transcodeClass),
        /*targetListener=*/ null,
        requestOptions,
        Executors.mainThreadExecutor());
}
复制代码

在调用 RequestBuilder#into 重载函数时,会先调用 GlideContext#buildImageViewTarget 函数构建一个 ViewTarget 对象并传入。

ViewTarget 是一个抽象类,所以我们有必要先弄清楚创建的 ViewTarget 实现类是什么。

我们先来看 GlideContext#buildImageViewTarget 函数。

// GlideContext.java
@NonNull
public <X> ViewTarget<ImageView, X> buildImageViewTarget(
      @NonNull ImageView imageView, @NonNull Class<X> transcodeClass)
{
    return imageViewTargetFactory.buildTarget(imageView, transcodeClass);
}

// ImageViewTargetFactory.java
public <Z> ViewTarget<ImageView, Z> buildTarget(
      @NonNull ImageView view, @NonNull Class<Z> clazz)
{
    // 根据 RequestBuilder 对象中 记录的 transcodeClass 进行判断,创建相应的实现类。
    // transcodeClass 默认为 Drawable.class
    if (Bitmap.class.equals(clazz))
    {
        return (ViewTarget<ImageView, Z>) new BitmapImageViewTarget(view);
    }
    else if (Drawable.class.isAssignableFrom(clazz)) // 此时 transcodeClass = Drawable.class
    {
        return (ViewTarget<ImageView, Z>) new DrawableImageViewTarget(view);
    }
    else
    {
        throw new IllegalArgumentException(
            "Unhandled class: " + clazz + ", try .as*(Class).transcode(ResourceTranscoder)");
    }
}
复制代码

现在我们知道了 GlideContext#buildImageViewTarget 函数返回的是 DrawableImageViewTarget 对象。

我们返回接着来看 RequestBuilder#into 重载函数。

// RequestBuilder.java
private <Y extends Target<TranscodeType>> Y into(
      @NonNull Y target, // DrawableImageViewTarget
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> options,
      Executor callbackExecutor
){
    ......
    // 构建一个 Request 请求
    Request request = buildRequest(target, targetListener, options, callbackExecutor);
    // 检查 DrawableImageViewTarget 中是否存在上一个 Request 请求
    Request previous = target.getRequest();
    if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(options, previous))
    {
        ......
        return target;
    }
    // 清除 RequestManager 中记录的上一个 Request 请求
    requestManager.clear(target);
    // 给 DrawableImageViewTarget 重新设置一个 Request 请求
    target.setRequest(request);
    requestManager.track(target, request);
}
复制代码

Request 是一个接口,所以我们有必要先弄清楚创建的 Request 实现类是什么。

我们先来看 RequestBuilder#buildRequest 函数。

// RequestBuilder.java
private Request buildRequest(
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor
){
    return buildRequestRecursive(
        /*requestLock=*/ new Object(),
        target,
        targetListener,
        /*parentCoordinator=*/ null,
        transitionOptions,
        requestOptions.getPriority(),
        requestOptions.getOverrideWidth(),
        requestOptions.getOverrideHeight(),
        requestOptions,
        callbackExecutor);
}

private Request buildRequestRecursive(
      Object requestLock,
      Target<TranscodeType> target,
      @Nullable RequestListener<TranscodeType> targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor
){
    ErrorRequestCoordinator errorRequestCoordinator = null;
    ......
    Request mainRequest = buildThumbnailRequestRecursive(
            requestLock,
            target,
            targetListener,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            requestOptions,
            callbackExecutor);

    // 此时 errorRequestCoordinator 为空,if 命中,之后的代码不执行
    if (errorRequestCoordinator == null)
    {
        return mainRequest;
    }
    ......
}

private Request buildThumbnailRequestRecursive(
      Object requestLock,
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      @Nullable RequestCoordinator parentCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      BaseRequestOptions<?> requestOptions,
      Executor callbackExecutor
){
    // 此时 thumbnailBuilder 为空
    if (thumbnailBuilder != null)
    {
        ......
    }
    // 此时 thumbSizeMultiplier 为空
    else if (thumbSizeMultiplier != null)
    {
        ......
    }
    else
    {
        return obtainRequest(
            requestLock,
            target,
            targetListener,
            requestOptions,
            parentCoordinator,
            transitionOptions,
            priority,
            overrideWidth,
            overrideHeight,
            callbackExecutor);
    }
}

private Request obtainRequest(
      Object requestLock,
      Target<TranscodeType> target,
      RequestListener<TranscodeType> targetListener,
      BaseRequestOptions<?> requestOptions,
      RequestCoordinator requestCoordinator,
      TransitionOptions<?, ? super TranscodeType> transitionOptions,
      Priority priority,
      int overrideWidth,
      int overrideHeight,
      Executor callbackExecutor
){
    return SingleRequest.obtain(
        context,
        glideContext,
        requestLock,
        model,
        transcodeClass,
        requestOptions,
        overrideWidth,
        overrideHeight,
        priority,
        target,
        targetListener,
        requestListeners,
        requestCoordinator,
        glideContext.getEngine(),
        transitionOptions.getTransitionFactory(),
        callbackExecutor);
}
复制代码

现在我们知道了 RequestBuilder#buildRequest 函数返回的是 SingleRequest 对象。

我们返回接着来看 RequestManager#track 函数。

// RequestManager.java
synchronized void track(@NonNull Target<?> target, 
                        @NonNull Request request // SingleRequest
){
    // 添加一个目标任务
    targetTracker.track(target);
    // 执行 Request 请求
    requestTracker.runRequest(request);
}

// RequestTracker.java
public void runRequest(@NonNull Request request)
{
    requests.add(request);
    // 判断是否暂停,此时 if 命中
    if (!isPaused)
    {
        request.begin();
    }
    else
    {
        request.clear();
        ......
        pendingRequests.add(request);
    }
}

// SingleRequest.java
@Override
public void begin()
{
    synchronized (requestLock)
    {
        ......
        status = Status.WAITING_FOR_SIZE;
        // 判断我们是否调用了 override 函数
        if (Util.isValidDimensions(overrideWidth, overrideHeight))
        {
            onSizeReady(overrideWidth, overrideHeight);
        }
        else
        {
            // target = DrawableImageViewTarget
            target.getSize(this);
        }
        ......
    }
}
复制代码

SingleRequest#begin 函数中,会判断我们是否调用了 override 函数来指定图片的宽高。

假设我们没有设置,我们接着看到 DrawableImageViewTarget#getSize 函数。

// ViewTarget.java(DrawableImageViewTarget 继承自 ViewTarget)
public void getSize(@NonNull SizeReadyCallback cb // SingleRequest
){
    sizeDeterminer.getSize(cb);
}

// ViewTarget$SizeDeterminer.java
void getSize(@NonNull SizeReadyCallback cb)
{
    // 根据 LayoutParams 计算图片目标宽高
    int currentWidth = getTargetWidth();
    int currentHeight = getTargetHeight();
    // 检查计算值是否合法,if 命中
    if (isViewStateAndSizeValid(currentWidth, currentHeight))
    {
        cb.onSizeReady(currentWidth, currentHeight);
        return;
    }
    ......
}
复制代码

可以看到无论有没有调用了 override 函数,最终都会调用到 SingleRequest#onSizeReady 函数。

// SingleRequest.java
@Override
public void onSizeReady(int width, int height)
{
    synchronized (requestLock)
    {
        ......
        status = Status.RUNNING;
        ......
        loadStatus = engine.load(
              glideContext,
              model,
              requestOptions.getSignature(),
              this.width,
              this.height,
              requestOptions.getResourceClass(),
              transcodeClass,
              priority,
              requestOptions.getDiskCacheStrategy(),
              requestOptions.getTransformations(),
              requestOptions.isTransformationRequired(),
              requestOptions.isScaleOnlyOrNoTransform(),
              requestOptions.getOptions(),
              requestOptions.isMemoryCacheable(),
              requestOptions.getUseUnlimitedSourceGeneratorsPool(),
              requestOptions.getUseAnimationPool(),
              requestOptions.getOnlyRetrieveFromCache(),
              this,
              callbackExecutor);
        ......
    }
}

// Engine.java
public <R> LoadStatus load(
      GlideContext glideContext,
      Object model,
      Key signature,
      int width,
      int height,
      Class<?> resourceClass,
      Class<R> transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map<Class<?>, Transformation<?>> transformations,
      boolean isTransformationRequired,
      boolean isScaleOnlyOrNoTransform,
      Options options,
      boolean isMemoryCacheable,
      boolean useUnlimitedSourceExecutorPool,
      boolean useAnimationPool,
      boolean onlyRetrieveFromCache,
      ResourceCallback cb, // SingleRequest
      Executor callbackExecutor
){
    ......
    // 根据 Request 请求构建一个 Key
    EngineKey key = keyFactory.buildKey(
            model,
            signature,
            width,
            height,
            transformations,
            resourceClass,
            transcodeClass,
            options);

    EngineResource<?> memoryResource;
    synchronized (this)
    {
        // 根据 Key 从缓存中进行查找资源
        memoryResource = loadFromMemory(key, isMemoryCacheable, startTime);
        // 如果缓存中查找不到资源
        if (memoryResource == null)
        {
            return waitForExistingOrStartNewJob(
                glideContext,
                model,
                signature,
                width,
                height,
                resourceClass,
                transcodeClass,
                priority,
                diskCacheStrategy,
                transformations,
                isTransformationRequired,
                isScaleOnlyOrNoTransform,
                options,
                isMemoryCacheable,
                useUnlimitedSourceExecutorPool,
                useAnimationPool,
                onlyRetrieveFromCache,
                cb,
                callbackExecutor,
                key,
                startTime);
        }
    }
    // 如果缓存中查找到了资源就回调返回
    cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE);
    return null;
}

private <R> LoadStatus waitForExistingOrStartNewJob(
      GlideContext glideContext,
      Object model,
      Key signature,
      int width,
      int height,
      Class<?> resourceClass,
      Class<R> transcodeClass,
      Priority priority,
      DiskCacheStrategy diskCacheStrategy,
      Map<Class<?>, Transformation<?>> transformations,
      boolean isTransformationRequired,
      boolean isScaleOnlyOrNoTransform,
      Options options,
      boolean isMemoryCacheable,
      boolean useUnlimitedSourceExecutorPool,
      boolean useAnimationPool,
      boolean onlyRetrieveFromCache,
      ResourceCallback cb,
      Executor callbackExecutor,
      EngineKey key,
      long startTime
){
    // 根据 Key 查看缓存中是否正在执行
    EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache);
    if (current != null)
    {
        // 如果正在执行,把数据回调出去
        current.addCallback(cb, callbackExecutor);
        if (VERBOSE_IS_LOGGABLE)
        {
            logWithTimeAndKey("Added to existing load", startTime, key);
        }
        return new LoadStatus(cb, current);
    }
    
    // 根据 Key 构建新的请求任务
    EngineJob<R> engineJob = engineJobFactory.build(
            key,
            isMemoryCacheable,
            useUnlimitedSourceExecutorPool,
            useAnimationPool,
            onlyRetrieveFromCache);
            
    DecodeJob<R> decodeJob = decodeJobFactory.build(
            glideContext,
            model,
            key,
            signature,
            width,
            height,
            resourceClass,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            onlyRetrieveFromCache,
            options,
            engineJob);

    // 把当前需要执行的请求任务的 Key 添加进缓存
    jobs.put(key, engineJob);
    // 执行请求任务的回调
    engineJob.addCallback(cb, callbackExecutor);
    // 开始执行请求任务
    engineJob.start(decodeJob);
    ......
    return new LoadStatus(cb, engineJob);
}

// EngineJob.java
public synchronized void start(DecodeJob<R> decodeJob)
{
    this.decodeJob = decodeJob;
    GlideExecutor executor = decodeJob.willDecodeFromCache() 
            ? diskCacheExecutor : getActiveSourceExecutor();
    executor.execute(decodeJob);
}
复制代码

GlideExecutor 是一个线程池,DecodeJob 是一个 Runnable。

SingleRequest#onSizeReady 函数中最终会构建一个请求任务并把请求任务提交给线程池执行异步请求。

既然 DecodeJob 是一个 Runnable,我们接着看 DecodeJob#run 函数。

// DecodeJob.java
@Override
public void run()
{
    ......
    runWrapped();
    ......
}

private void runWrapped()
{
    // runReason 初始值为 INITIALIZE,此时 runReason = INITIALIZE
    switch (runReason)
    {
        case INITIALIZE:
            // 获取资源状态(查看资源是否在磁盘缓存中)
            stage = getNextStage(Stage.INITIALIZE);
            // 根据当前资源状态,获取资源执行器
            currentGenerator = getNextGenerator();
            // 启动资源执行器
            runGenerators();
            break;
        ......
    }
}
复制代码

我们先来看 DecodeJob#getNextStage 函数。

// DecodeJob.java
private Stage getNextStage(Stage current)
{
    switch (current)
    {
        case INITIALIZE:
            // 尝试从本地磁盘缓存中解码资源数据,此时 decodeCachedResource 返回 false
            return diskCacheStrategy.decodeCachedResource()
                ? Stage.RESOURCE_CACHE
                : getNextStage(Stage.RESOURCE_CACHE); // 递归调用
        case RESOURCE_CACHE:
            // 尝试从本地磁盘缓存中解码资源数据,此时 decodeCachedData 返回 false
            return diskCacheStrategy.decodeCachedData()
                ? Stage.DATA_CACHE
                : getNextStage(Stage.DATA_CACHE); // 递归调用
        case DATA_CACHE:
            // onlyRetrieveFromCache 默认为 false,此时为 false
            return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
        case SOURCE:
        case FINISHED:
            return Stage.FINISHED;
        default:
            throw new IllegalArgumentException("Unrecognized stage: " + current);
    }
}
复制代码

现在我们知道了 DecodeJob#getNextStage 函数最终会返回 Stage.SOURCE。

我们接着来看 DecodeJob#getNextGenerator 函数。

// DecodeJob.java
private DataFetcherGenerator getNextGenerator()
{
    // 此时 stage = Stage.SOURCE
    switch (stage)
    {
        ......
        case SOURCE:
            return new SourceGenerator(decodeHelper, this);
        ......
    }
}
复制代码

现在我们知道了 DecodeJob#getNextGenerator 函数会返回 SourceGenerator。

我们返回接着来看 DecodeJob#runGenerators 函数。

// DecodeJob.java
private void runGenerators()
{
    ......
    boolean isStarted = false;
    while (!isCancelled
        && currentGenerator != null
        && !(isStarted = currentGenerator.startNext()))
    {
        stage = getNextStage(stage);
        currentGenerator = getNextGenerator();

        if (stage == Stage.SOURCE)
        {
            reschedule();
            return;
        }
    }
    ......
}

// SourceGenerator.java
@Override
public boolean startNext()
{
    ......
    loadData = null;
    boolean started = false;
    while (!started && hasNextModelLoader())
    {
        // 获取一个 ModelLoad 加载器
        loadData = helper.getLoadData().get(loadDataListIndex++);
        if (loadData != null
            && (helper.getDiskCacheStrategy().isDataCacheable(loadData.fetcher.getDataSource())
                || helper.hasLoadPath(loadData.fetcher.getDataClass())))
        {
            started = true;
            startNextLoad(loadData);
        }
    }
    return started;
}

// DecodeHelper.java
List<LoadData<?>> getLoadData()
{
    // isLoadDataSet 默认为 false,if 命中
    if (!isLoadDataSet)
    {
        isLoadDataSet = true;
        loadData.clear();
        // 根据我们输入的 URL(model)匹配在 Glide 中注册过的加载器
        List<ModelLoader<Object, ?>> modelLoaders = glideContext.getRegistry().getModelLoaders(model);
        // 遍历匹配的加载器
        for (int i = 0, size = modelLoaders.size(); i < size; i++)
        {
            ModelLoader<Object, ?> modelLoader = modelLoaders.get(i);
            LoadData<?> current = modelLoader.buildLoadData(model, width, height, options);
            if (current != null)
            {
                loadData.add(current);
            }
        }
    }
    return loadData;
}
复制代码

这里会比较难理解,什么叫 “在 Glide 中注册过的加载器” ?

其实前面在说 Glide 的构造函数时,省略了一部分的细节。

// Glide.java
Glide(
      @NonNull Context context,
      @NonNull Engine engine,
      @NonNull MemoryCache memoryCache,
      @NonNull BitmapPool bitmapPool,
      @NonNull ArrayPool arrayPool,
      @NonNull RequestManagerRetriever requestManagerRetriever,
      @NonNull ConnectivityMonitorFactory connectivityMonitorFactory,
      int logLevel,
      @NonNull RequestOptionsFactory defaultRequestOptionsFactory,
      @NonNull Map<Class<?>, TransitionOptions<?, ?>> defaultTransitionOptions,
      @NonNull List<RequestListener<Object>> defaultRequestListeners,
      boolean isLoggingRequestOriginsEnabled,
      boolean isImageDecoderEnabledForBitmaps
){
    ......
    registry = new Registry();
    ......
    registry
        ......
        .append(String.class, InputStream.class, new StringLoader.StreamFactory())
        ......
        .append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory())
    ......
    glideContext = new GlideContext(
            context,
            arrayPool,
            registry,
            imageViewTargetFactory,
            defaultRequestOptionsFactory,
            defaultTransitionOptions,
            defaultRequestListeners,
            engine,
            isLoggingRequestOriginsEnabled,
            logLevel);
}
复制代码

可以看到在 Glide 的构造函数中,会注册所有的加载器。根据我们输入的 URL 会自动匹配到 HttpGlideUrlLoader 这个加载器。

问题来了,我们输入的 URL 是以字符串的形式输入的,为什么匹配出来的是 GlideUrl.class,而不是 String.class?

GlideUrl 是 Glide 内部对于 URL 的一个包装类。在匹配加载器的过程中,Glide 内部会自动判断我们输入的字符串内容是不是一个 URL;如果判断为是 URL,就会将我们输入的字符串包装成 GlideUrl。

可以看到在 Glide 源码中关于 GlideUrl 的注释:

表示 http/https URL 的字符串的包装器,负责确保正确转义URL,并避免只需要字符串URL而不需要URL对象的加载程序进行不必要的URL实例化。

我们接着来看 HttpGlideUrlLoader#buildLoadData 函数。

// HttpGlideUrlLoader.java
@Override
public LoadData<InputStream> buildLoadData(
      @NonNull GlideUrl model, int width, int height, @NonNull Options options
){
    GlideUrl url = model;
    if (modelCache != null)
    {
        url = modelCache.get(model, 0, 0);
        if (url == null)
        {
            modelCache.put(model, 0, 0, model);
            url = model;
        }
    }
    int timeout = options.get(TIMEOUT);
    return new LoadData<>(url, new HttpUrlFetcher(url, timeout));
}
复制代码

可以看到最终 HttpGlideUrlLoader#buildLoadData 函数会返回一个 LoadData 对象,该 LoadData 对象的 fetcher 字段保存着一个 HttpUrlFetcher 对象。

我们返回继续看到 SourceGenerator#startNextLoad 函数。

// SourceGenerator.java
private void startNextLoad(final LoadData<?> toStart)
{
    // 此时 loadData.fetcher = HttpUrlFetcher
    loadData.fetcher.loadData(
        helper.getPriority(),
        new DataCallback<Object>()
        {
            @Override
            public void onDataReady(@Nullable Object data)
            {
                if (isCurrentRequest(toStart))
                {
                    onDataReadyInternal(toStart, data);
                }
            }

            @Override
            public void onLoadFailed(@NonNull Exception e)
            {
                if (isCurrentRequest(toStart))、
                {
                    onLoadFailedInternal(toStart, e);
                }
            }
        });
}

// HttpUrlFetcher.java
@Override
public void loadData(
      @NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback
){
    ......
    try
    {
        // Http 请求,返回一个 InputStream 输入流
        InputStream result = loadDataWithRedirects(glideUrl.toURL(), 0, 
                null, glideUrl.getHeaders());
        // 将 InputStream 以回调形式回调出去
        callback.onDataReady(result);
    }
    catch (IOException e)
    {
        ......
        callback.onLoadFailed(e);
    }
    ......
}

// SourceGenerator.java
void onDataReadyInternal(
        LoadData<?> loadData, 
        Object data // 网络请求返回的 InputStream
){
    DiskCacheStrategy diskCacheStrategy = helper.getDiskCacheStrategy();
    // 由于我们没有设置 diskCacheStrategy 缓存策略,if 不命中,执行 else
    if (data != null && diskCacheStrategy.isDataCacheable(loadData.fetcher.getDataSource()))
    {
        dataToCache = data;
        cb.reschedule();
    }
    else
    {
        // cb = DecodeJob
        cb.onDataFetcherReady(
            loadData.sourceKey,
            data,
            loadData.fetcher,
            loadData.fetcher.getDataSource(),
            originalKey);
    }
}

// DecodeJob.java
@Override
public void onDataFetcherReady(
      Key sourceKey, 
      Object data, 
      DataFetcher<?> fetcher, 
      DataSource dataSource, 
      Key attemptedKey
){
    this.currentSourceKey = sourceKey; // 当前返回数据(InputStream) 的 Key(GlideUrl)
    this.currentData = data; // 当前返回的数据(InputStream)
    this.currentFetcher = fetcher; // 当前返回数据的执行器,此时为 HttpUrlFetcher
    this.currentDataSource = dataSource; // 当前返回数据的类型
    this.currentAttemptingKey = attemptedKey;
    
    // 此时仍是异步线程,Thread.currentThread() = currentThread,执行 else
    if (Thread.currentThread() != currentThread)
    {
        runReason = RunReason.DECODE_DATA;
        callback.reschedule(this);
    }
    else
    {
        GlideTrace.beginSection("DecodeJob.decodeFromRetrievedData");
        try
        {
            // 解析返回的数据
            decodeFromRetrievedData();
        }
        finally
        {
            GlideTrace.endSection();
        }
    }
}

private void decodeFromRetrievedData()
{
    ......
    Resource<R> resource = null;
    ......
    // 解析 InputStream
    resource = decodeFromData(currentFetcher, currentData, currentDataSource);
    ......
}

private <Data> Resource<R> decodeFromData(
      DataFetcher<?> fetcher, 
      Data data, 
      DataSource dataSource) throws GlideException
{
    ......
    // 通过 HttpUrlFetcher 解析 InputStream
    Resource<R> result = decodeFromFetcher(data, dataSource);
    ......
    return result;
}

private <Data> Resource<R> decodeFromFetcher(Data data, DataSource dataSource)
      throws GlideException
{
    // 获取 InputStream 的解析器 LoadPath
    LoadPath<Data, ?, R> path = decodeHelper.getLoadPath((Class<Data>) data.getClass());
    // 通过 LoadPath 解析器来解析 InputStream
    return runLoadPath(data, dataSource, path);
}

private <Data, ResourceType> Resource<R> runLoadPath(
      Data data, DataSource dataSource, LoadPath<Data, ResourceType, R> path)
      throws GlideException
{
    Options options = getOptionsWithHardwareConfig(dataSource);
    // 因为此时 data = InputStream,所以 rewinder = InputStreamRewinder
    DataRewinder<Data> rewinder = glideContext.getRegistry().getRewinder(data);
    ......
    // 调用 LoadPath 解析器的解析函数
    return path.load(
        rewinder, options, width, height, new DecodeCallback<ResourceType>(dataSource));
}

// LoadPath.java
public Resource<Transcode> load(
      DataRewinder<Data> rewinder,
      @NonNull Options options,
      int width,
      int height,
      DecodePath.DecodeCallback<ResourceType> decodeCallback)
      throws GlideException
{
    ......
    return loadWithExceptionList(rewinder, options, width, height, decodeCallback, throwables);
    ......
}

private Resource<Transcode> loadWithExceptionList(
      DataRewinder<Data> rewinder,
      @NonNull Options options,
      int width,
      int height,
      DecodePath.DecodeCallback<ResourceType> decodeCallback,
      List<Throwable> exceptions)
      throws GlideException
{
    Resource<Transcode> result = null;
    // 遍历 LoadPath 内部存储的 DecodePath 集合,通过他们来解析数据
    for (int i = 0, size = decodePaths.size(); i < size; i++)
    {
        DecodePath<Data, ResourceType, Transcode> path = decodePaths.get(i);
        // 真正解析数据的地方
        result = path.decode(rewinder, width, height, options, decodeCallback);
        ......
        if (result != null)
        {
            break;
        }
    }
    ......
    return result;
}

// DecodePath.java
public Resource<Transcode> decode(
      DataRewinder<DataType> rewinder,
      int width,
      int height,
      @NonNull Options options,
      DecodeCallback<ResourceType> callback) // callback = DecodeJob
      throws GlideException
{
    // 将数据(InputStream)解析成中间资源(Bitmap)
    Resource<ResourceType> decoded = decodeResource(rewinder, width, height, options);
    // 数据解析完后回调出去
    Resource<ResourceType> transformed = callback.onResourceDecoded(decoded);
    // 此时 transcoder = BitmapDrawableTranscoder
    return transcoder.transcode(transformed, options);
}
复制代码

这个解析的过程还是很繁琐的,但是胜利就在眼前了,我们先来看 DecodePath#decodeResource 函数是如何将 InputStream 解析成 Bitmap 的。

// DecodePath.java
@NonNull
private Resource<ResourceType> decodeResource(
      DataRewinder<DataType> rewinder, int width, int height, @NonNull Options options)
      throws GlideException
{
    ......
    return decodeResourceWithList(rewinder, width, height, options, exceptions);
    ......
}

@NonNull
private Resource<ResourceType> decodeResourceWithList(
      DataRewinder<DataType> rewinder,
      int width,
      int height,
      @NonNull Options options,
      List<Throwable> exceptions)
      throws GlideException
{
    Resource<ResourceType> result = null;
    // 遍历 DecodePath 内部存储的 ResourceDecoder 集合,通过他们来解析数据
    for (int i = 0, size = decoders.size(); i < size; i++)
    {
        ResourceDecoder<DataType, ResourceType> decoder = decoders.get(i);
        ......
        // 此时 decoder = StreamBitmapDecoder
        result = decoder.decode(data, width, height, options);
        ......
        if (result != null)
        {
            break;
        }
    }
    ......
    return result;
}

// StreamBitmapDecoder.java
@Override
public Resource<Bitmap> decode(
      @NonNull InputStream source, int width, int height, @NonNull Options options)
      throws IOException
{
    ......
    // invalidatingStream 其实就是 source,只不过做了几层封装
    return downsampler.decode(invalidatingStream, width, height, options, callbacks);
    ......
}

// Downsampler.java
public Resource<Bitmap> decode(
      InputStream is,
      int requestedWidth,
      int requestedHeight,
      Options options,
      DecodeCallbacks callbacks)
      throws IOException
{
    return decode(
        new ImageReader.InputStreamImageReader(is, parsers, byteArrayPool),
        requestedWidth,
        requestedHeight,
        options,
        callbacks);
}

private Resource<Bitmap> decode(
      ImageReader imageReader,
      int requestedWidth,
      int requestedHeight,
      Options options,
      DecodeCallbacks callbacks)
      throws IOException
{
    ......
    // 在 decodeFromWrappedStreams 中会对 InputStream 进行采样压缩,最终解码成 Bitmap
    Bitmap result = decodeFromWrappedStreams(
              imageReader,
              bitmapFactoryOptions,
              downsampleStrategy,
              decodeFormat,
              preferredColorSpace,
              isHardwareConfigAllowed,
              requestedWidth,
              requestedHeight,
              fixBitmapToRequestedDimensions,
              callbacks);
    return BitmapResource.obtain(result, bitmapPool);
    ......
}
复制代码

我们返回继续看到 DecodeJob#onResourceDecoded 函数回调。

// DecodeJob.java
@NonNull
@Override
public Resource<Z> onResourceDecoded(@NonNull Resource<Z> decoded)
{
    return DecodeJob.this.onResourceDecoded(dataSource, decoded);
}

@Synthetic
@NonNull
<Z> Resource<Z> onResourceDecoded(DataSource dataSource, @NonNull Resource<Z> decoded)
{
    // 获取资源类型(Bitmap)
    Class<Z> resourceSubClass = (Class<Z>) decoded.get().getClass();
    Transformation<Z> appliedTransformation = null;
    Resource<Z> transformed = decoded;
    // 此时 dataSource = DataSource.REMOTE,if 命中
    if (dataSource != DataSource.RESOURCE_DISK_CACHE)
    {
        appliedTransformation = decodeHelper.getTransformation(resourceSubClass);
        transformed = appliedTransformation.transform(glideContext, decoded, width, height);
    }
    ......
    // 构建数据磁盘缓存的编码策略
    final EncodeStrategy encodeStrategy;
    final ResourceEncoder<Z> encoder;
    if (decodeHelper.isResourceEncoderAvailable(transformed))
    {
        encoder = decodeHelper.getResultEncoder(transformed);
        encodeStrategy = encoder.getEncodeStrategy(options);
    }
    else
    {
        encoder = null;
        encodeStrategy = EncodeStrategy.NONE;
    }
    // 根据编码策略,构建用于磁盘缓存的 Key
    Resource<Z> result = transformed;
    boolean isFromAlternateCacheKey = !decodeHelper.isSourceKey(currentSourceKey);
    // 判断 diskCacheStrategy 的缓存策略(应缓存最终转换的资源),if 命中
    if (diskCacheStrategy.isResourceCacheable(
            isFromAlternateCacheKey, dataSource, encodeStrategy))
    {
        ......
        final Key key;
        // 此时 encodeStrategy = SOURCE
        switch (encodeStrategy)
        {
            case SOURCE:
                key = new DataCacheKey(currentSourceKey, signature);
                break;
            ......
        }
        // 初始化编码管理者,用于提交磁盘缓存
        LockedResource<Z> lockedResult = LockedResource.obtain(transformed);
        deferredEncodeManager.init(key, encoder, lockedResult);
        result = lockedResult;
    }
    // 返回转换后的 Bitmap
    return result;
}
复制代码

我们返回继续看到 BitmapDrawableTranscoder#transcode 函数。

// BitmapDrawableTranscoder.java
@Nullable
@Override
public Resource<BitmapDrawable> transcode(
      @NonNull Resource<Bitmap> toTranscode, @NonNull Options options)
{
    return LazyBitmapDrawableResource.obtain(resources, toTranscode);
}

// LazyBitmapDrawableResource.java
@Nullable
public static Resource<BitmapDrawable> obtain(
      @NonNull Resources resources, @Nullable Resource<Bitmap> bitmapResource)
{
    if (bitmapResource == null)
    {
        return null;
    }
    return new LazyBitmapDrawableResource(resources, bitmapResource);
}

private LazyBitmapDrawableResource(
      @NonNull Resources resources, @NonNull Resource<Bitmap> bitmapResource)
{
    this.resources = Preconditions.checkNotNull(resources);
    this.bitmapResource = Preconditions.checkNotNull(bitmapResource);
}
复制代码

我们返回继续看到 DecodeJob#decodeFromRetrievedData 函数。

// DecodeJob.java
private void decodeFromRetrievedData()
{
    ......
    Resource<R> resource = null;
    ......
    // 此时 resource = LazyBitmapDrawableResource
    resource = decodeFromData(currentFetcher, currentData, currentDataSource);
    ......
    // 此时解析完成,通知返回
    if (resource != null)
    {
        notifyEncodeAndRelease(resource, currentDataSource);
    }
    else
    {
        // 如果解析失败就会再次执行一遍 runGenerators 流程
        runGenerators();
    }
}

private void notifyEncodeAndRelease(Resource<R> resource, DataSource dataSource)
{
    ......
    Resource<R> result = resource;
    ......
    // 通知调用层
    notifyComplete(result, dataSource);

    stage = Stage.ENCODE;
    // 此时 hasResourceToEncode 函数返回 true,if 命中
    if (deferredEncodeManager.hasResourceToEncode())
    {
        // 将 Bitmap 资源缓存到磁盘中
        deferredEncodeManager.encode(diskCacheProvider, options);
    }
    ......
    // 执行资源释放操作
    onEncodeComplete();
}

private void notifyComplete(Resource<R> resource, DataSource dataSource)
{
    setNotifiedOrThrow();
    // 此时 callback = EngineJob
    callback.onResourceReady(resource, dataSource);
}

// EngineJob.java
@Override
public void onResourceReady(Resource<R> resource, DataSource dataSource)
{
    synchronized (this)
    {
        this.resource = resource;
        this.dataSource = dataSource;
    }
    notifyCallbacksOfResult();
}

void notifyCallbacksOfResult()
{
    ResourceCallbacksAndExecutors copy;
    EngineResource<?> localResource;
    ......
    // 此时 cbs = SingleRequest
    copy = cbs.copy();
    ......
    // 构建 EngineResource,对 Bitmap 资源进行封装
    engineResource = engineResourceFactory.build(resource, isCacheable, key, resourceListener);
    ......
    // 回调上层,通知 Engine 引擎任务完成,将 Bitmap 资源添加到内存缓存中
    engineJobListener.onEngineJobComplete(this, localKey, localResource);
    // 回调返回 Bitmap 资源
    for (final ResourceCallbackAndExecutor entry : copy)
    {
        // 返回主线程执行回调
        entry.executor.execute(new CallResourceReady(entry.cb));
    }
    ......
}

// EngineJob$CallResourceReady.java
@Override
public void run()
{
    ......
    if (cbs.contains(cb))
    {
        ......
        callCallbackOnResourceReady(cb);
        ......
    }
    ......
}

void callCallbackOnResourceReady(ResourceCallback cb)
{
    ......
    // 回调返回 SingleRequest
    cb.onResourceReady(engineResource, dataSource);
    ......
}

// SingleRequest.java
@Override
public void onResourceReady(Resource<?> resource, DataSource dataSource)
{
    ......
    // 取出 Drawable 资源,此时就把 Bitmap 转换成了 Drawable。
    // LazyBitmapDrawableResource 内部会将 Bitmap 转换成 Drawable,通过 get 函数返回
    Object received = resource.get();
    ......
    onResourceReady((Resource<R>) resource, (R) received, dataSource);
    ......
}

private void onResourceReady(Resource<R> resource, R result, DataSource dataSource)
{
    boolean isFirstResource = isFirstReadyResource();
    status = Status.COMPLETE;
    this.resource = resource;
    ......
    boolean anyListenerHandledUpdatingTarget = false;
    ......
    // 此时 anyListenerHandledUpdatingTarget = false,if 命中
    if (!anyListenerHandledUpdatingTarget)
    {
        Transition<? super R> animation = animationFactory.build(dataSource, isFirstResource);
        // 此时 target = DrawableImageViewTarget
        target.onResourceReady(result, animation);
    }
    ......
}

// ImageViewTarget.java(DrawableImageViewTarget 继承自 ImageViewTarget)
@Override
public void onResourceReady(@NonNull Z resource, @Nullable Transition<? super Z> transition)
{
    ......
    setResourceInternal(resource);
    ......
}

private void setResourceInternal(@Nullable Z resource)
{
    setResource(resource);
    ......
}

// DrawableImageViewTarget.java
@Override
protected void setResource(@Nullable Drawable resource)
{
    // 设置图片资源
    view.setImageDrawable(resource);
}
复制代码

最终将图片资源回调到 DrawableImageViewTarget 中,显示到 UI 界面上。

总结

这就是 Glide 加载图片的完整流程。当然这是最简单的路线,因为 Glide 框架很庞大,其中有许多的细节没有深究,因为这些涉及到 Glide 的其他功能,但不是最主要的,我们的目的是要弄清楚整体的流程。

最后可以用一张图来大致总结一下:

未命名文件.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享