Android Glide 配置与初始化模块源码深度剖析

发布于:2025-03-10 ⋅ 阅读:(10) ⋅ 点赞:(0)

一、引言

在 Android 开发中,图片加载是一个常见且重要的功能。Glide 作为一款强大的图片加载库,因其高效、灵活和易于使用的特点,被广泛应用于各种 Android 应用中。Glide 的配置与初始化模块是整个库的基础,它允许开发者根据不同的需求对 Glide 进行定制化设置,如缓存策略、图片解码格式、自定义组件等。本文将深入 Glide 源码,详细剖析其配置与初始化模块的实现原理和工作流程。

二、配置与初始化模块概述

2.1 模块的作用

Glide 的配置与初始化模块主要负责以下几个方面的工作:

  • 全局配置:允许开发者对 Glide 的各种行为进行全局配置,如设置缓存大小、自定义组件等。
  • 组件注册:开发者可以通过该模块注册自定义的组件,如 ModelLoaderResourceDecoder 等,以支持新的数据源和图片格式。
  • 生命周期管理:确保 Glide 与应用的生命周期进行正确的绑定,避免内存泄漏。

2.2 核心组件

该模块的核心组件包括:

  • GlideBuilder:用于构建 Glide 实例,提供了一系列方法来设置 Glide 的各种配置。
  • GlideModule(在 Glide 4.x 及以后版本为 AppGlideModuleLibraryGlideModule):提供了一种在应用启动时配置 Glide 的方式,开发者可以在 GlideModule 中注册自定义的组件、修改默认配置等。
  • Glide:Glide 库的核心类,负责管理图片加载请求、缓存、线程池等。

2.3 整体架构

Glide 配置与初始化模块的整体架构可以分为以下几个层次:

  1. 应用层:开发者在应用代码中调用 Glide 的初始化方法,并进行相关配置。
  2. 配置层GlideBuilderGlideModule 负责接收开发者的配置信息,并进行相应的设置。
  3. 核心层Glide 类根据配置信息进行初始化,创建各种组件和服务。

三、GlideBuilder 源码分析

3.1 类定义及属性

java

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.Engine;
import com.bumptech.glide.load.engine.cache.DiskCache;
import com.bumptech.glide.load.engine.cache.DiskCacheFactory;
import com.bumptech.glide.load.engine.cache.MemoryCache;
import com.bumptech.glide.load.engine.cache.M.cache.MemorySizeCalculator;
import com.bumptech.glide.load.engine.executor.GlideExecutor;
import com.bumptech.glide.manager.ConnectivityMonitorFactory;
import com.bumptech.glide.manager.DefaultConnectivityMonitorFactory;
import com.bumptech.glide.manager.Lifecycle;
import com.bumptech.glide.manager.RequestManagerRetriever;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.ViewTarget;
import com.bumptech.glide.util.Preconditions;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;

// GlideBuilder 类,用于构建 Glide 实例
public final class GlideBuilder {
    // 应用上下文
    private final Context context;
    // 内存缓存工厂
    private MemoryCache.Factory memoryCacheFactory;
    // 磁盘缓存工厂
    private DiskCache.Factory diskCacheFactory;
    // 引擎工厂
    private Engine.Factory engineFactory;
    // 解码格式
    private DecodeFormat decodeFormat = DecodeFormat.DEFAULT;
    // 默认的请求选项
    private RequestOptions defaultRequestOptions = new RequestOptions();
    // 连接监控工厂
    private ConnectivityMonitorFactory connectivityMonitorFactory;
    // 后台线程池
    private GlideExecutor sourceExecutor;
    // 磁盘缓存线程池
    private GlideExecutor diskCacheExecutor;
    // 动画帧线程池
    private GlideExecutor animationExecutor;
    // 生命周期
    private Lifecycle lifecycle;
    // 请求管理器检索器
    private RequestManagerRetriever.RequestManagerFactory requestManagerFactory;
    // 视图目标的默认布局参数
    private ViewTarget.LayoutParamsFactory defaultLayoutParamsFactory;
    // 注册表,用于注册各种组件
    private final Registry registry = new Registry();
    // 全局日志级别
    private int logLevel = android.util.Log.DEBUG;
    // 动画处理类
    private Handler mainHandler;
    // 内存大小计算器
    private MemorySizeCalculator memorySizeCalculator;
    // 组件清单解析器
    private final List<com.bumptech.glide.module.GlideModule> manifestModules = new ArrayList<>();
    // 自定义的 Glide 模块
    private com.bumptech.glide.module.GlideModule customModule;
}

GlideBuilder 类中,定义了一系列属性,用于存储 Glide 的各种配置信息。这些属性包括内存缓存工厂、磁盘缓存工厂、引擎工厂、解码格式、默认请求选项等。通过这些属性,开发者可以对 Glide 的各个方面进行定制化配置。

3.2 构造函数

java

/**
 * 构造函数,初始化 GlideBuilder 实例
 * 
 * @param context 应用上下文
 */
GlideBuilder(@NonNull Context context) {
    // 保存应用上下文
    this.context = context.getApplicationContext();
}

构造函数接收一个 Context 对象,并将其转换为应用上下文进行保存。这是为了避免因传入的 Context 生命周期过短而导致的内存泄漏问题。

3.3 配置方法

3.3.1 内存缓存配置

java

/**
 * 设置内存缓存工厂
 * 
 * @param memoryCacheFactory 内存缓存工厂
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setMemoryCache(@NonNull MemoryCache.Factory memoryCacheFactory) {
    // 检查传入的内存缓存工厂是否为空
    this.memoryCacheFactory = Preconditions.checkNotNull(memoryCacheFactory);
    return this;
}

setMemoryCache 方法用于设置内存缓存工厂。开发者可以通过该方法自定义内存缓存的实现,例如使用自定义的 LruResourceCache 或其他内存缓存策略。

3.3.2 磁盘缓存配置

java

/**
 * 设置磁盘缓存工厂
 * 
 * @param diskCacheFactory 磁盘缓存工厂
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setDiskCache(@NonNull DiskCache.Factory diskCacheFactory) {
    // 检查传入的磁盘缓存工厂是否为空
    this.diskCacheFactory = Preconditions.checkNotNull(diskCacheFactory);
    return this;
}

setDiskCache 方法用于设置磁盘缓存工厂。开发者可以通过该方法自定义磁盘缓存的实现,例如使用自定义的 DiskLruCacheWrapper 或其他磁盘缓存策略。

3.3.3 引擎配置

java

/**
 * 设置引擎工厂
 * 
 * @param engineFactory 引擎工厂
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setEngine(@NonNull Engine.Factory engineFactory) {
    // 检查传入的引擎工厂是否为空
    this.engineFactory = Preconditions.checkNotNull(engineFactory);
    return this;
}

setEngine 方法用于设置引擎工厂。引擎是 Glide 的核心组件之一,负责管理图片的加载、缓存和资源回收等操作。开发者可以通过该方法自定义引擎的实现。

3.3.4 解码格式配置

java

/**
 * 设置解码格式
 * 
 * @param decodeFormat 解码格式
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setDecodeFormat(@NonNull DecodeFormat decodeFormat) {
    // 检查传入的解码格式是否为空
    this.decodeFormat = Preconditions.checkNotNull(decodeFormat);
    return this;
}

setDecodeFormat 方法用于设置图片的解码格式。不同的解码格式会影响图片的质量和内存占用,开发者可以根据实际需求选择合适的解码格式。

3.3.5 默认请求选项配置

java

/**
 * 设置默认的请求选项
 * 
 * @param defaultRequestOptions 默认请求选项
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setDefaultRequestOptions(@NonNull RequestOptions defaultRequestOptions) {
    // 检查传入的默认请求选项是否为空
    this.defaultRequestOptions = Preconditions.checkNotNull(defaultRequestOptions);
    return this;
}

setDefaultRequestOptions 方法用于设置默认的请求选项。默认请求选项会应用到所有的图片加载请求中,开发者可以通过该方法设置一些通用的请求参数,如占位图、错误图等。

3.3.6 连接监控工厂配置

java

/**
 * 设置连接监控工厂
 * 
 * @param factory 连接监控工厂
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setConnectivityMonitorFactory(@NonNull ConnectivityMonitorFactory factory) {
    // 检查传入的连接监控工厂是否为空
    this.connectivityMonitorFactory = Preconditions.checkNotNull(factory);
    return this;
}

setConnectivityMonitorFactory 方法用于设置连接监控工厂。连接监控工厂用于创建连接监控器,监控网络连接状态的变化,以便在网络连接可用时自动恢复图片加载任务。

3.3.7 线程池配置

java

/**
 * 设置后台线程池
 * 
 * @param sourceExecutor 后台线程池
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setSourceExecutor(@NonNull GlideExecutor sourceExecutor) {
    // 检查传入的后台线程池是否为空
    this.sourceExecutor = Preconditions.checkNotNull(sourceExecutor);
    return this;
}

/**
 * 设置磁盘缓存线程池
 * 
 * @param diskCacheExecutor 磁盘缓存线程池
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setDiskCacheExecutor(@NonNull GlideExecutor diskCacheExecutor) {
    // 检查传入的磁盘缓存线程池是否为空
    this.diskCacheExecutor = Preconditions.checkNotNull(diskCacheExecutor);
    return this;
}

/**
 * 设置动画帧线程池
 * 
 * @param animationExecutor 动画帧线程池
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setAnimationExecutor(@NonNull GlideExecutor animationExecutor) {
    // 检查传入的动画帧线程池是否为空
    this.animationExecutor = Preconditions.checkNotNull(animationExecutor);
    return this;
}

这些方法分别用于设置后台线程池、磁盘缓存线程池和动画帧线程池。不同的线程池用于执行不同类型的任务,如后台线程池用于执行网络请求和图片解码任务,磁盘缓存线程池用于执行磁盘缓存的读写任务,动画帧线程池用于执行动画帧的加载和处理任务。

3.3.8 其他配置方法

java

/**
 * 设置生命周期
 * 
 * @param lifecycle 生命周期
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setLifecycle(@NonNull Lifecycle lifecycle) {
    // 检查传入的生命周期是否为空
    this.lifecycle = Preconditions.checkNotNull(lifecycle);
    return this;
}

/**
 * 设置请求管理器工厂
 * 
 * @param factory 请求管理器工厂
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setRequestManagerFactory(@NonNull RequestManagerRetriever.RequestManagerFactory factory) {
    // 检查传入的请求管理器工厂是否为空
    this.requestManagerFactory = Preconditions.checkNotNull(factory);
    return this;
}

/**
 * 设置视图目标的默认布局参数工厂
 * 
 * @param factory 视图目标的默认布局参数工厂
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setDefaultLayoutParamsFactory(@NonNull ViewTarget.LayoutParamsFactory factory) {
    // 检查传入的视图目标的默认布局参数工厂是否为空
    this.defaultLayoutParamsFactory = Preconditions.checkNotNull(factory);
    return this;
}

/**
 * 设置全局日志级别
 * 
 * @param logLevel 全局日志级别
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setLogLevel(int logLevel) {
    this.logLevel = logLevel;
    return this;
}

/**
 * 设置动画处理类
 * 
 * @param mainHandler 动画处理类
 * @return GlideBuilder 实例,用于链式调用
 */
@NonNull
public GlideBuilder setMainHandler(@NonNull Handler mainHandler) {
    // 检查传入的动画处理类是否为空
    this.mainHandler = Preconditions.checkNotNull(mainHandler);
    return this;
}

这些方法分别用于设置生命周期、请求管理器工厂、视图目标的默认布局参数工厂、全局日志级别和动画处理类。开发者可以通过这些方法对 Glide 的各个方面进行更细致的配置。

3.4 构建 Glide 实例

java

/**
 * 构建 Glide 实例
 * 
 * @return Glide 实例
 */
@NonNull
public 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 (memoryCacheFactory == null) {
        memoryCacheFactory = new LruResourceCache.Factory(memorySizeCalculator.getMemoryCacheSize());
    }

    // 如果未设置磁盘缓存工厂,使用默认的磁盘缓存工厂
    if (diskCacheFactory == null) {
        diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    // 如果未设置引擎工厂,使用默认的引擎工厂
    if (engineFactory == null) {
        engineFactory = new Engine.Factory(diskCacheFactory, diskCacheExecutor, sourceExecutor);
    }

    // 如果未设置连接监控工厂,使用默认的连接监控工厂
    if (connectivityMonitorFactory == null) {
        connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();
    }

    // 如果未设置动画处理类,创建一个默认的动画处理类
    if (mainHandler == null) {
        mainHandler = new Handler(Looper.getMainLooper());
    }

    // 创建引擎实例
    Engine engine = engineFactory.build(
            memoryCacheFactory.build(),
            diskCacheExecutor,
            sourceExecutor,
            animationExecutor,
            isActiveResourceRetentionAllowed);

    // 创建请求管理器检索器
    RequestManagerRetriever requestManagerRetriever = new RequestManagerRetriever(requestManagerFactory);

    // 创建 Glide 实例
    Glide glide = new Glide(
            context,
            engine,
            memoryCacheFactory.build(),
            diskCacheFactory,
            registry,
            animationExecutor,
            memorySizeCalculator,
            connectivityMonitorFactory,
            logLevel,
            defaultRequestOptions.lock(),
            defaultTransitionOptions,
            requestManagerRetriever,
            mainHandler,
            defaultLayoutParamsFactory);

    // 注册所有的 Glide 模块
    for (com.bumptech.glide.module.GlideModule module : manifestModules) {
        module.registerComponents(context, glide, registry);
    }
    if (customModule != null) {
        customModule.registerComponents(context, glide, registry);
    }

    return glide;
}

build 方法用于构建 Glide 实例。在该方法中,会检查各个配置项是否已经设置,如果未设置,则使用默认的配置。然后根据配置信息创建引擎、请求管理器检索器等组件,并最终创建 Glide 实例。最后,会注册所有的 GlideModule,以便对 Glide 进行进一步的配置和扩展。

四、GlideModule 源码分析

4.1 GlideModule 概述

在 Glide 4.x 及以后版本中,GlideModule 被拆分为 AppGlideModuleLibraryGlideModuleAppGlideModule 用于在应用级别进行配置,而 LibraryGlideModule 用于在库级别进行配置。

4.2 AppGlideModule 源码分析

4.2.1 类定义及属性

java

import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;

// 标记该类为 AppGlideModule
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
    // 可以在这里添加自定义的配置方法和属性
}

AppGlideModule 是一个抽象类,开发者需要创建一个继承自 AppGlideModule 的子类,并使用 @GlideModule 注解进行标记。

4.2.2 主要方法

java

@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {
    // 在这里可以对 GlideBuilder 进行配置
    builder.setMemoryCache(new LruResourceCache(10 * 1024 * 1024)); // 设置内存缓存大小为 10MB
    builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, 50 * 1024 * 1024)); // 设置磁盘缓存大小为 50MB
}

@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
    // 在这里可以注册自定义的组件
    registry.append(MyModel.class, InputStream.class, new MyModelLoader.Factory());
}

@Override
public boolean isManifestParsingEnabled() {
    // 是否启用组件清单解析
    return false;
}
  • applyOptions 方法:用于对 GlideBuilder 进行配置,开发者可以在该方法中设置内存缓存、磁盘缓存、解码格式等配置信息。
  • registerComponents 方法:用于注册自定义的组件,如 ModelLoaderResourceDecoder 等。通过该方法,开发者可以扩展 Glide 的功能,支持新的数据源和图片格式。
  • isManifestParsingEnabled 方法:用于控制是否启用组件清单解析。在 Glide 4.x 及以后版本中,建议将该方法返回 false,以避免组件清单解析带来的性能开销。

4.3 LibraryGlideModule 源码分析

4.3.1 类定义及属性

java

import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.LibraryGlideModule;

// 标记该类为 LibraryGlideModule
@GlideModule
public class MyLibraryGlideModule extends LibraryGlideModule {
    // 可以在这里添加自定义的配置方法和属性
}

LibraryGlideModule 也是一个抽象类,开发者需要创建一个继承自 LibraryGlideModule 的子类,并使用 @GlideModule 注解进行标记。

4.3.2 主要方法

java

@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
    // 在这里可以注册自定义的组件
    registry.append(MyModel.class, InputStream.class, new MyModelLoader.Factory());
}

LibraryGlideModule 主要用于在库级别注册自定义的组件。与 AppGlideModule 不同的是,LibraryGlideModule 没有 applyOptions 方法,因为库级别通常不进行全局配置,而是专注于组件的注册。

五、Glide 初始化流程分析

5.1 初始化入口

在应用代码中,通常通过以下方式初始化 Glide:

java

GlideBuilder builder = new GlideBuilder(context);
Glide glide = builder.build(context);

或者使用 Glide.get(context) 方法,该方法会在内部调用 GlideBuilder 进行初始化:

java

Glide glide = Glide.get(context);

5.2 初始化流程

  1. 创建 GlideBuilder 实例:在初始化过程中,首先会创建一个 GlideBuilder 实例,用于接收和保存配置信息。
  2. 配置 GlideBuilder:开发者可以通过 GlideBuilder 的各种配置方法,对 Glide 的内存缓存、磁盘缓存、引擎、解码格式等进行配置。
  3. 注册 GlideModule:在 build 方法中,会注册所有的 GlideModule,包括 AppGlideModuleLibraryGlideModule。在 GlideModule 中,开发者可以对 GlideBuilder 进行进一步的配置,或者注册自定义的组件。
  4. 创建核心组件:根据配置信息,build 方法会创建引擎、请求管理器检索器等核心组件。
  5. 创建 Glide 实例:最后,build 方法会创建 Glide 实例,并将配置信息和核心组件传递给 Glide 实例。

5.3 初始化流程的源码分析

java

// Glide 类中的 get 方法
public static Glide get(@NonNull Context context) {
    // 检查传入的上下文是否为空
    if (glide == null) {
        synchronized (Glide.class) {
            if (glide == null) {
                // 获取应用上下文
                Context applicationContext = context.getApplicationContext();
                // 获取组件清单解析器
                List<com.bumptech.glide.module.GlideModule> manifestModules = new ManifestParser(applicationContext).parse();
                // 创建 GlideBuilder 实例
                GlideBuilder builder = new GlideBuilder(applicationContext);
                // 创建 AppGlideModule 实例
                AppGlideModule appGlideModule = new GeneratedAppGlideModuleImpl();
                // 应用 AppGlideModule 中的配置
                appGlideModule.applyOptions(applicationContext, builder);
                // 注册 LibraryGlideModule 中的组件
                for (com.bumptech.glide.module.GlideModule module : manifestModules) {
                    module.registerComponents(applicationContext, builder, builder.getRegistry());
                }
                // 注册 AppGlideModule 中的组件
                appGlideModule.registerComponents(applicationContext, builder, builder.getRegistry());
                // 构建 Glide 实例
                glide = builder.build(applicationContext);
            }
        }
    }
    return glide;
}

get 方法中,会首先检查 Glide 实例是否已经创建。如果未创建,则会进行以下操作:

  1. 获取应用上下文。
  2. 使用 ManifestParser 解析组件清单,获取所有的 LibraryGlideModule
  3. 创建 GlideBuilder 实例。
  4. 创建 AppGlideModule 实例,并调用其 applyOptions 方法对 GlideBuilder 进行配置。
  5. 注册所有 LibraryGlideModuleAppGlideModule 中的组件。
  6. 调用 GlideBuilderbuild 方法构建 Glide 实例。

六、自定义配置和组件注册

6.1 自定义内存缓存

开发者可以通过 GlideBuildersetMemoryCache 方法自定义内存缓存。以下是一个自定义内存缓存的示例:

java

// 自定义内存缓存工厂
class MyMemoryCacheFactory implements MemoryCache.Factory {
    @Override
    public MemoryCache build() {
        return new LruResourceCache(20 * 1024 * 1024); // 设置内存缓存大小为 20MB
    }
}

// 在应用代码中使用自定义内存缓存
GlideBuilder builder = new GlideBuilder(context);
builder.setMemoryCache(new MyMemoryCacheFactory());
Glide glide = builder.build(context);

在这个示例中,我们创建了一个自定义的内存缓存工厂 MyMemoryCacheFactory,并在 build 方法中返回一个 LruResourceCache 实例,设置其大小为 20MB。然后通过 GlideBuildersetMemoryCache 方法使用该自定义内存缓存工厂。

6.2 自定义磁盘缓存

开发者可以通过 GlideBuildersetDiskCache 方法自定义磁盘缓存。以下是一个自定义磁盘缓存的示例:

java

// 自定义磁盘缓存工厂
class MyDiskCacheFactory implements DiskCache.Factory {
    @Override
    public DiskCache build() {
        return DiskLruCacheWrapper.create(new File(context.getExternalCacheDir(), "my_cache"),

网站公告

今日签到

点亮在社区的每一天
去签到