Android Glide 请求构建与管理模块原理深入剖析

一、整体描述

在 Android 开发中,图片加载是一个常见且关键的功能。Glide 作为一款强大的图片加载库,以其高效、灵活和易于使用的特性,被广泛应用于各种 Android 应用中。请求构建与管理模块是 Glide 中非常重要的一部分,它负责创建和管理图片加载请求,包括设置请求的各种参数、管理请求的生命周期以及协调不同组件之间的工作。本文将深入 Glide 源码,详细分析请求构建与管理模块的原理和工作流程。

二、请求构建与管理模块概述

2.1 模块的主要功能

  • 请求参数设置:允许开发者设置图片加载请求的各种参数,如图片来源、占位图、错误图、图片尺寸、缩放类型等。
  • 请求构建:根据设置的参数构建一个完整的图片加载请求。
  • 请求生命周期管理:确保请求在合适的时机被执行、暂停、恢复或取消,避免内存泄漏和不必要的资源消耗。
  • 请求队列管理:对多个请求进行排队和调度,确保请求的有序执行。

2.2 核心组件

  • RequestBuilder:用于构建图片加载请求的核心类,提供了一系列方法来设置请求的各种参数。
  • RequestManager:负责管理请求的生命周期,与 Activity 或 Fragment 的生命周期进行绑定,确保请求在 Activity 或 Fragment 销毁时自动取消。
  • RequestManagerRetriever :用于获取 RequestManager 实例,根据不同的上下文(如 Activity、Fragment)返回相应的 RequestManager
  • Request:表示一个具体的图片加载请求,包含了请求的各种参数和状态信息。

2.3 整体架构

请求构建与管理模块的整体架构可以分为以下几个层次:

  1. 应用层 :开发者在应用代码中使用 RequestBuilder 构建请求,并通过 RequestManager 发起请求。

  2. 构建层RequestBuilder 根据开发者设置的参数构建 Request 对象。

  3. 管理层RequestManager 管理 Request 的生命周期,RequestManagerRetriever 负责获取 RequestManager 实例。

  4. 执行层Request 对象被提交给 Glide 的核心引擎进行实际的图片加载操作。

三、RequestBuilder 源码分析

3.1 类定义及属性

java

java 复制代码
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.annotation.CheckResult;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.BaseRequestOptions;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.TransitionOptions;
import java.io.File;
import java.net.URL;
import java.util.UUID;

// RequestBuilder 类,用于构建图片加载请求
public class RequestBuilder<TranscodeType> implements Cloneable {
    // Glide 实例
    protected final Glide glide;
    // 请求管理器
    protected final RequestManager requestManager;
    // 请求选项
    protected RequestOptions requestOptions;
    // 过渡选项
    protected TransitionOptions<?, ? super TranscodeType> transitionOptions;
    // 图片来源
    protected Object model;
    // 请求监听器列表
    protected final List<RequestListener<TranscodeType>> requestListeners = new ArrayList<>();
    // 是否仅从缓存加载
    protected boolean onlyRetrieveFromCache;
    // 上下文
    protected final Context context;
    // 请求的唯一标识符
    protected final UUID requestId = UUID.randomUUID();
}

RequestBuilder 类中,定义了一系列属性,用于存储请求的各种信息。glide 是 Glide 的核心实例,requestManager 负责管理请求的生命周期,requestOptions 存储了请求的各种选项,model 表示图片的来源,requestListeners 用于存储请求监听器,onlyRetrieveFromCache 表示是否仅从缓存加载图片。

3.2 构造函数

java

java 复制代码
/**
 * 构造函数,初始化 RequestBuilder 实例
 * 
 * @param glide Glide 实例
 * @param requestManager 请求管理器
 * @param transcodeClass 转换类型的类
 * @param context 上下文
 */
protected RequestBuilder(
        @NonNull Glide glide,
        @NonNull RequestManager requestManager,
        @NonNull Class<TranscodeType> transcodeClass,
        @NonNull Context context) {
    this.glide = glide;
    this.requestManager = requestManager;
    this.requestOptions = requestManager.getDefaultRequestOptions();
    this.transitionOptions = getDefaultTransitionOptions(glide, transcodeClass);
    this.context = context;
}

构造函数接收 Glide 实例、RequestManager 实例、转换类型的类和上下文作为参数。在构造函数中,会将 requestOptions 初始化为 RequestManager 的默认请求选项,transitionOptions 初始化为默认的过渡选项。

3.3 请求参数设置方法

3.3.1 设置图片来源

java

java 复制代码
/**
 * 设置图片来源为文件
 * 
 * @param file 文件对象
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable File file) {
    return loadGeneric(file);
}

/**
 * 设置图片来源为 URI
 * 
 * @param uri URI 对象
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable android.net.Uri uri) {
    return loadGeneric(uri);
}

/**
 * 设置图片来源为 URL
 * 
 * @param url URL 对象
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> load(@Nullable URL url) {
    return loadGeneric(url);
}

// 其他 load 方法...

/**
 * 通用的设置图片来源方法
 * 
 * @param model 图片来源对象
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
private RequestBuilder<TranscodeType> loadGeneric(@Nullable Object model) {
    this.model = model;
    return this;
}

load 方法用于设置图片的来源,可以是文件、URI、URL 等。这些方法最终都会调用 loadGeneric 方法,将图片来源对象存储在 model 属性中。

3.3.2 设置占位图和错误图

java

java 复制代码
/**
 * 设置占位图
 * 
 * @param drawableId 占位图的资源 ID
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> placeholder(@DrawableRes int drawableId) {
    return apply(requestOptions.placeholder(drawableId));
}

/**
 * 设置错误图
 * 
 * @param drawableId 错误图的资源 ID
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> error(@DrawableRes int drawableId) {
    return apply(requestOptions.error(drawableId));
}

// 其他占位图和错误图设置方法...

/**
 * 应用请求选项
 * 
 * @param options 请求选项
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> apply(@NonNull BaseRequestOptions<?> options) {
    this.requestOptions = this.requestOptions.apply(options);
    return this;
}

placeholdererror 方法用于设置占位图和错误图。这些方法会调用 apply 方法,将新的请求选项应用到当前的 requestOptions 中。

3.3.3 设置缓存策略

java

java 复制代码
/**
 * 设置磁盘缓存策略
 * 
 * @param strategy 磁盘缓存策略
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> diskCacheStrategy(@NonNull DiskCacheStrategy strategy) {
    return apply(requestOptions.diskCacheStrategy(strategy));
}

diskCacheStrategy 方法用于设置磁盘缓存策略,同样会调用 apply 方法更新 requestOptions

3.3.4 其他参数设置方法

java

java 复制代码
// 设置图片尺寸
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> override(int width, int height) {
    return apply(requestOptions.override(width, height));
}

// 设置缩放类型
@NonNull
@CheckResult
public RequestBuilder<TranscodeType> centerCrop() {
    return apply(requestOptions.centerCrop());
}

// 其他参数设置方法...

这些方法用于设置图片的尺寸、缩放类型等其他参数,同样会调用 apply 方法更新 requestOptions

3.4 构建请求方法

java

java 复制代码
/**
 * 构建并提交请求到目标视图
 * 
 * @param target 目标视图
 * @return 当前 RequestBuilder 实例,用于链式调用
 */
@NonNull
public RequestBuilder<TranscodeType> into(@NonNull Target<TranscodeType> target) {
    Util.assertMainThread();
    Request request = buildRequest(target);
    Request previous = target.getRequest();
    if (request.isEquivalentTo(previous)
            && !isSkipMemoryCacheWithCompletePreviousRequest(previous)) {
        request.recycle();
        // 如果请求相同且不需要跳过内存缓存,则不重新发起请求
        if (!Preconditions.checkNotNull(previous).isRunning()) {
            previous.begin();
        }
        return this;
    }
    requestManager.clear(target);
    target.setRequest(request);
    requestManager.track(target, request);
    return this;
}

/**
 * 构建请求对象
 * 
 * @param target 目标视图
 * @return 请求对象
 */
private Request buildRequest(Target<TranscodeType> target) {
    return buildRequestRecursive(target, /*parentCoordinator=*/ null);
}

/**
 * 递归构建请求对象
 * 
 * @param target 目标视图
 * @param parentCoordinator 父协调器
 * @return 请求对象
 */
private Request buildRequestRecursive(
        Target<TranscodeType> target, @Nullable RequestCoordinator parentCoordinator) {
    Request mainRequest = buildThumbnailRequestRecursive(target, parentCoordinator);
    if (thumbnailBuilder != null) {
        Request thumbnailRequest =
                thumbnailBuilder.buildRequestRecursive(target, mainRequest);
        mainRequest =
                new ThumbnailRequestCoordinator(thumbnailRequest, mainRequest, parentCoordinator);
    }
    return mainRequest;
}

/**
 * 构建缩略图请求对象
 * 
 * @param target 目标视图
 * @param parentCoordinator 父协调器
 * @return 请求对象
 */
private Request buildThumbnailRequestRecursive(
        Target<TranscodeType> target, @Nullable RequestCoordinator parentCoordinator) {
    RequestOptions requestOptions = this.requestOptions;
    if (thumbnailRequestOptions != null) {
        requestOptions = requestOptions.apply(thumbnailRequestOptions);
    }
    return obtainRequest(target, requestOptions, transitionOptions, parentCoordinator);
}

/**
 * 获取请求对象
 * 
 * @param target 目标视图
 * @param requestOptions 请求选项
 * @param transitionOptions 过渡选项
 * @param parentCoordinator 父协调器
 * @return 请求对象
 */
private Request obtainRequest(
        Target<TranscodeType> target,
        RequestOptions requestOptions,
        TransitionOptions<?, ? super TranscodeType> transitionOptions,
        @Nullable RequestCoordinator parentCoordinator) {
    return SingleRequest.obtain(
            context,
            glide,
            model,
            requestOptions.getSignature(),
            requestOptions.getTranscodeClass(),
            requestOptions.getPriority(),
            requestOptions.getDiskCacheStrategy(),
            requestOptions.getTransformations(),
            requestOptions.isTransformationRequired(),
            requestOptions.isScaleOnlyOrNoTransform(),
            requestOptions.getOptions(),
            requestOptions.getOverrideWidth(),
            requestOptions.getOverrideHeight(),
            requestOptions.getErrorPlaceholder(),
            requestOptions.getFallbackDrawable(),
            requestOptions.getPlaceholderDrawable(),
            requestOptions.getPlaceholderId(),
            requestOptions.getErrorId(),
            requestOptions.getFallbackId(),
            requestOptions.isSkipMemoryCache(),
            requestOptions.getUseUnlimitedSourceGeneratorsPool(),
            requestOptions.getUseAnimationPool(),
            requestOptions.getOnlyRetrieveFromCache(),
            target,
            requestListeners,
            requestCoordinator,
            glide.getEngine(),
            transitionOptions);
}

into 方法用于构建并提交请求到目标视图。在该方法中,会先调用 buildRequest 方法构建请求对象,然后检查当前请求是否与之前的请求相同,如果相同且不需要跳过内存缓存,则不重新发起请求。否则,会清除目标视图上的之前的请求,设置新的请求,并将请求交给 RequestManager 进行跟踪。

buildRequest 方法会递归调用 buildRequestRecursive 方法来构建请求对象。如果存在缩略图请求,会将缩略图请求和主请求封装在 ThumbnailRequestCoordinator 中。

obtainRequest 方法用于获取 SingleRequest 实例,将请求的各种参数传递给 SingleRequest 进行初始化。

四、RequestManager 源码分析

4.1 类定义及属性

java

java 复制代码
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.manager.ConnectivityMonitor;
import com.bumptech.glide.manager.ConnectivityMonitorFactory;
import com.bumptech.glide.manager.Lifecycle;
import com.bumptech.glide.manager.LifecycleListener;
import com.bumptech.glide.manager.RequestTracker;
import com.bumptech.glide.manager.TargetTracker;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.util.Util;

import java.util.Collections;
import java.util.Set;
import java.util.WeakHashMap;

// RequestManager 类,负责管理请求的生命周期
public class RequestManager implements LifecycleListener {
    // Glide 实例
    protected final Glide glide;
    // 上下文
    protected final Context context;
    // 请求跟踪器
    protected final RequestTracker requestTracker;
    // 目标跟踪器
    protected final TargetTracker targetTracker = new TargetTracker();
    // 生命周期对象
    protected final Lifecycle lifecycle;
    // 连接监控器
    private final ConnectivityMonitor connectivityMonitor;
    // 默认请求选项
    private final RequestOptions defaultRequestOptions;
    // 请求构建器
    private final RequestBuilder<Drawable> requestBuilder;
    // 活动目标集合
    private final Set<Target<?>> pendingTargets =
            Collections.newSetFromMap(new WeakHashMap<Target<?>, Boolean>());
    // 是否已经开始
    private boolean isPaused;
}

RequestManager 类中,定义了一系列属性,用于管理请求的生命周期。glide 是 Glide 的核心实例,requestTracker 用于跟踪请求的状态,targetTracker 用于跟踪目标视图,lifecycle 与 Activity 或 Fragment 的生命周期进行绑定,connectivityMonitor 用于监控网络连接状态。

4.2 构造函数

java

java 复制代码
/**
 * 构造函数,初始化 RequestManager 实例
 * 
 * @param glide Glide 实例
 * @param lifecycle 生命周期对象
 * @param requestManagerTreeNode 请求管理器树节点
 * @param context 上下文
 */
public RequestManager(
        @NonNull Glide glide,
        @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode,
        @NonNull Context context) {
    this(
            glide,
            lifecycle,
            requestManagerTreeNode,
            new RequestTracker(),
            glide.getConnectivityMonitorFactory(),
            context);
}

/**
 * 构造函数,初始化 RequestManager 实例
 * 
 * @param glide Glide 实例
 * @param lifecycle 生命周期对象
 * @param requestManagerTreeNode 请求管理器树节点
 * @param requestTracker 请求跟踪器
 * @param factory 连接监控器工厂
 * @param context 上下文
 */
RequestManager(
        @NonNull Glide glide,
        @NonNull Lifecycle lifecycle,
        @NonNull RequestManagerTreeNode requestManagerTreeNode,
        @NonNull RequestTracker requestTracker,
        @NonNull ConnectivityMonitorFactory factory,
        @NonNull Context context) {
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.context = context.getApplicationContext();
    this.requestTracker = requestTracker;
    defaultRequestOptions = glide.getDefaultRequestOptions();
    requestBuilder = new RequestBuilder<>(glide, this, Drawable.class, context);
    connectivityMonitor =
            factory.build(
                    context.getApplicationContext(),
                    new RequestManagerConnectivityListener(requestTracker));

    if (Util.isOnBackgroundThread()) {
        // 如果在后台线程,立即开始请求
        mainHandler.post(addSelfToLifecycle);
    } else {
        // 如果在主线程,直接添加到生命周期
        lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    setRequestOptions(defaultRequestOptions);
}

构造函数接收 Glide 实例、Lifecycle 实例、RequestManagerTreeNode 实例、RequestTracker 实例、ConnectivityMonitorFactory 实例和上下文作为参数。在构造函数中,会初始化各种属性,创建 RequestBuilder 实例,构建连接监控器,并将 RequestManager 添加到生命周期中。

4.3 请求生命周期管理方法

4.3.1 开始请求

java

java 复制代码
@Override
public void onStart() {
    resumeRequests();
    targetTracker.onStart();
}

/**
 * 恢复请求
 */
public void resumeRequests() {
    isPaused = false;
    requestTracker.resumeRequests();
    for (Target<?> target : pendingTargets) {
        Request request = target.getRequest();
        if (Util.isValidRequest(request)) {
            request.begin();
        }
    }
    pendingTargets.clear();
}

onStart 方法会在 Activity 或 Fragment 开始时被调用,会调用 resumeRequests 方法恢复请求。resumeRequests 方法会将 isPaused 标志设置为 false,并调用 requestTrackerresumeRequests 方法恢复所有暂停的请求。同时,会遍历 pendingTargets 集合,开始所有有效的请求,并清空该集合。

4.3.2 暂停请求

java

java 复制代码
@Override
public void onStop() {
    pauseRequests();
    targetTracker.onStop();
}

/**
 * 暂停请求
 */
public void pauseRequests() {
    isPaused = true;
    requestTracker.pauseRequests();
    for (Target<?> target : targetTracker.getAll()) {
        Request request = target.getRequest();
        if (Util.isValidRequest(request)) {
            pendingTargets.add(target);
            request.clear();
        }
    }
}

onStop 方法会在 Activity 或 Fragment 停止时被调用,会调用 pauseRequests 方法暂停请求。pauseRequests 方法会将 isPaused 标志设置为 true,并调用 requestTrackerpauseRequests 方法暂停所有正在执行的请求。同时,会遍历 targetTracker 中的所有目标视图,将有效的请求添加到 pendingTargets 集合中,并清除请求。

4.3.3 销毁请求

java

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

/**
 * 清除目标视图上的请求
 * 
 * @param target 目标视图
 */
public void clear(@NonNull Target<?> target) {
    Request request = target.getRequest();
    if (request != null) {
        requestTracker.clearRequest(request);
        target.setRequest(null);
    }
    targetTracker.remove(target);
    if (target instanceof ViewTarget) {
        View view = ((ViewTarget<?, ?>) target).getView();
        if (view != null) {
            view.setTag(R.id.glide_tag, null);
        }
    }
}

onDestroy 方法会在 Activity 或 Fragment 销毁时被调用,会清除所有目标视图上的请求,停止请求跟踪器,从生命周期中移除 RequestManager 和连接监控器,并移除回调。clear 方法用于清除目标视图上的请求,会调用 requestTrackerclearRequest 方法清除请求,并将目标视图的请求设置为 null

4.4 请求跟踪方法

java

java 复制代码
/**
 * 跟踪请求
 * 
 * @param target 目标视图
 * @param request 请求对象
 */
public void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
}

track 方法用于跟踪请求,会将目标视图添加到 targetTracker 中,并调用 requestTrackerrunRequest 方法执行请求。

五、RequestManagerRetriever 源码分析

5.1 类定义及属性

java

java 复制代码
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.manager.RequestManagerFragment;
import com.bumptech.glide.manager.SupportRequestManagerFragment;
import com.bumptech.glide.util.Util;

import java.util.HashMap;
import java.util.Map;

// RequestManagerRetriever 类,用于获取 RequestManager 实例
public class RequestManagerRetriever implements RequestManagerTreeNode {
    // 请求管理器工厂
    private final RequestManagerFactory factory;
    // 支持库 Fragment 的请求管理器映射
    private final Map<androidx.fragment.app.Fragment, SupportRequestManagerFragment> supportRequestManagerFragments =
            new HashMap<>();
    // 原生 Fragment 的请求管理器映射
    private final Map<Fragment, RequestManagerFragment> requestManagerFragments = new HashMap<>();
    // 主线程处理程序
    private final Handler mainHandler = new Handler(Looper.getMainLooper());
}

RequestManagerRetriever 类中,定义了一系列属性,用于存储请求管理器的映射。factory 是请求管理器工厂,supportRequestManagerFragments 用于存储支持库 Fragment 的请求管理器,requestManagerFragments 用于存储原生 Fragment 的请求管理器。

5.2 构造函数

java

java 复制代码
/**
 * 构造函数,初始化 RequestManagerRetriever 实例
 * 
 * @param factory 请求管理器工厂
 */
public RequestManagerRetriever(@Nullable RequestManagerFactory factory) {
    this.factory = factory != null ? factory : DEFAULT_FACTORY;
}

构造函数接收一个 RequestManagerFactory 实例作为参数,如果传入的工厂为 null,则使用默认的工厂。

5.3 获取 RequestManager 方法

5.3.1 从 Activity 获取

java

java 复制代码
/**
 * 从 Activity 获取 RequestManager 实例
 * 
 * @param activity Activity 实例
 * @return RequestManager 实例
 */
@NonNull
public RequestManager get(@NonNull Activity activity) {
    if (Util.isOnBackgroundThread()) {
        return get(activity.getApplicationContext());
    } else {
        assertNotDestroyed(activity);
        android.app.FragmentManager fm = activity.getFragmentManager();
        return supportFragmentGet(activity, fm);
    }
}

get 方法用于从 Activity 获取 RequestManager 实例。如果在后台线程,会调用 get 方法传入应用上下文;如果在主线程,会检查 Activity 是否已经销毁,并调用 supportFragmentGet 方法获取 RequestManager

5.3.2 从 FragmentActivity 获取

java

java 复制代码
/**
 * 从 FragmentActivity 获取 RequestManager 实例
 * 
 * @param activity FragmentActivity 实例
 * @return RequestManager 实例
 */
@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {
    if (Util.isOnBackgroundThread()) {
        return get(activity.getApplicationContext());
    } else {
        assertNotDestroyed(activity);
        androidx.fragment.app.FragmentManager fm = activity.getSupportFragmentManager();
        return supportFragmentGet(activity, fm);
    }
}

get 方法用于从 FragmentActivity 获取 RequestManager 实例,

接着继续分析

六、Request 类及其子类源码分析

6.1 Request 类概述

Request 类是一个抽象类,它定义了图片加载请求的基本行为和状态。其主要职责包括发起请求、暂停请求、恢复请求、清除请求以及管理请求的生命周期等。

java

java 复制代码
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

// Request 抽象类,定义了图片加载请求的基本行为
public interface Request {
    // 开始请求
    void begin();
    // 暂停请求
    void pause();
    // 清除请求
    void clear();
    // 判断请求是否正在运行
    boolean isRunning();
    // 判断请求是否已完成
    boolean isComplete();
    // 判断请求是否已清除
    boolean isCleared();
    // 判断请求是否已失败
    boolean isFailed();
    // 获取请求的错误信息
    @Nullable
    Throwable getError();
    // 判断两个请求是否等价
    boolean isEquivalentTo(@Nullable Request other);
    // 回收请求资源
    void recycle();
}

6.2 SingleRequest 类分析

6.2.1 类定义及属性

SingleRequestRequest 的一个具体实现类,它代表一个单一的图片加载请求。

java

java 复制代码
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.engine.Engine;
import com.bumptech.glide.load.engine.EngineJob;
import com.bumptech.glide.load.engine.EngineResource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestCoordinator;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.SingleRequest;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import com.bumptech.glide.request.transition.TransitionFactory;
import com.bumptech.glide.util.LogTime;
import com.bumptech.glide.util.Util;

import java.util.ArrayList;
import java.util.List;

// SingleRequest 类,代表一个单一的图片加载请求
public class SingleRequest<ResourceType> implements Request, EngineJobListener {
    // 上下文
    private final Context context;
    // Glide 实例
    private final Glide glide;
    // 图片来源
    private final Object model;
    // 请求的唯一签名
    private final Key signature;
    // 转换类型的类
    private final Class<ResourceType> transcodeClass;
    // 请求的优先级
    private final Priority priority;
    // 磁盘缓存策略
    private final DiskCacheStrategy diskCacheStrategy;
    // 转换操作列表
    private final Map<Class<?>, Transformation<?>> transformations;
    // 是否需要转换
    private final boolean isTransformationRequired;
    // 是否仅进行缩放或不进行转换
    private final boolean isScaleOnlyOrNoTransform;
    // 请求选项
    private final Options options;
    // 覆盖的宽度
    private final int overrideWidth;
    // 覆盖的高度
    private final int overrideHeight;
    // 错误占位图
    private final Drawable errorPlaceholder;
    // 回退占位图
    private final Drawable fallbackDrawable;
    // 占位图
    private final Drawable placeholderDrawable;
    // 占位图资源 ID
    private final int placeholderId;
    // 错误图资源 ID
    private final int errorId;
    // 回退图资源 ID
    private final int fallbackId;
    // 是否跳过内存缓存
    private final boolean isSkipMemoryCache;
    // 是否使用无限制的源生成器池
    private final boolean useUnlimitedSourceGeneratorsPool;
    // 是否使用动画池
    private final boolean useAnimationPool;
    // 是否仅从缓存加载
    private final boolean onlyRetrieveFromCache;
    // 目标视图
    private final Target<ResourceType> target;
    // 请求监听器列表
    private final List<RequestListener<ResourceType>> requestListeners;
    // 请求协调器
    private final RequestCoordinator requestCoordinator;
    // 引擎
    private final Engine engine;
    // 过渡选项
    private final TransitionOptions<?, ? super ResourceType> transitionOptions;
    // 过渡工厂
    private final TransitionFactory<? super ResourceType> transitionFactory;
    // 开始时间
    private long startTime;
    // 引擎作业
    private EngineJob<ResourceType> engineJob;
    // 资源
    private Resource<ResourceType> resource;
    // 错误信息
    private GlideException error;
    // 请求状态
    private Status status;
    // 资源是否已设置到目标视图
    private boolean isResourceSet;
    // 过渡是否已完成
    private boolean isTransitioning;
    // 请求是否已被回收
    private boolean isRecycled;

    // 枚举类型,表示请求的状态
    private enum Status {
        PENDING, // 待处理
        RUNNING, // 运行中
        WAITING_FOR_SIZE, // 等待尺寸
        COMPLETE, // 完成
        FAILED, // 失败
        CLEARED, // 已清除
        PAUSED // 暂停
    }
}

6.2.2 构造函数

java

java 复制代码
/**
 * 构造函数,初始化 SingleRequest 实例
 * 
 * @param context 上下文
 * @param glide Glide 实例
 * @param model 图片来源
 * @param signature 请求的唯一签名
 * @param transcodeClass 转换类型的类
 * @param priority 请求的优先级
 * @param diskCacheStrategy 磁盘缓存策略
 * @param transformations 转换操作列表
 * @param isTransformationRequired 是否需要转换
 * @param isScaleOnlyOrNoTransform 是否仅进行缩放或不进行转换
 * @param options 请求选项
 * @param overrideWidth 覆盖的宽度
 * @param overrideHeight 覆盖的高度
 * @param errorPlaceholder 错误占位图
 * @param fallbackDrawable 回退占位图
 * @param placeholderDrawable 占位图
 * @param placeholderId 占位图资源 ID
 * @param errorId 错误图资源 ID
 * @param fallbackId 回退图资源 ID
 * @param isSkipMemoryCache 是否跳过内存缓存
 * @param useUnlimitedSourceGeneratorsPool 是否使用无限制的源生成器池
 * @param useAnimationPool 是否使用动画池
 * @param onlyRetrieveFromCache 是否仅从缓存加载
 * @param target 目标视图
 * @param requestListeners 请求监听器列表
 * @param requestCoordinator 请求协调器
 * @param engine 引擎
 * @param transitionOptions 过渡选项
 */
private SingleRequest(
        Context context,
        Glide glide,
        Object model,
        Key signature,
        Class<ResourceType> transcodeClass,
        Priority priority,
        DiskCacheStrategy diskCacheStrategy,
        Map<Class<?>, Transformation<?>> transformations,
        boolean isTransformationRequired,
        boolean isScaleOnlyOrNoTransform,
        Options options,
        int overrideWidth,
        int overrideHeight,
        Drawable errorPlaceholder,
        Drawable fallbackDrawable,
        Drawable placeholderDrawable,
        int placeholderId,
        int errorId,
        int fallbackId,
        boolean isSkipMemoryCache,
        boolean useUnlimitedSourceGeneratorsPool,
        boolean useAnimationPool,
        boolean onlyRetrieveFromCache,
        Target<ResourceType> target,
        List<RequestListener<ResourceType>> requestListeners,
        RequestCoordinator requestCoordinator,
        Engine engine,
        TransitionOptions<?, ? super ResourceType> transitionOptions) {
    this.context = context;
    this.glide = glide;
    this.model = model;
    this.signature = signature;
    this.transcodeClass = transcodeClass;
    this.priority = priority;
    this.diskCacheStrategy = diskCacheStrategy;
    this.transformations = transformations;
    this.isTransformationRequired = isTransformationRequired;
    this.isScaleOnlyOrNoTransform = isScaleOnlyOrNoTransform;
    this.options = options;
    this.overrideWidth = overrideWidth;
    this.overrideHeight = overrideHeight;
    this.errorPlaceholder = errorPlaceholder;
    this.fallbackDrawable = fallbackDrawable;
    this.placeholderDrawable = placeholderDrawable;
    this.placeholderId = placeholderId;
    this.errorId = errorId;
    this.fallbackId = fallbackId;
    this.isSkipMemoryCache = isSkipMemoryCache;
    this.useUnlimitedSourceGeneratorsPool = useUnlimitedSourceGeneratorsPool;
    this.useAnimationPool = useAnimationPool;
    this.onlyRetrieveFromCache = onlyRetrieveFromCache;
    this.target = target;
    this.requestListeners = requestListeners;
    this.requestCoordinator = requestCoordinator;
    this.engine = engine;
    this.transitionOptions = transitionOptions;
    this.transitionFactory = transitionOptions.getFactory();
    this.status = Status.PENDING;
}

/**
 * 静态方法,用于获取 SingleRequest 实例
 * 
 * @param context 上下文
 * @param glide Glide 实例
 * @param model 图片来源
 * @param signature 请求的唯一签名
 * @param transcodeClass 转换类型的类
 * @param priority 请求的优先级
 * @param diskCacheStrategy 磁盘缓存策略
 * @param transformations 转换操作列表
 * @param isTransformationRequired 是否需要转换
 * @param isScaleOnlyOrNoTransform 是否仅进行缩放或不进行转换
 * @param options 请求选项
 * @param overrideWidth 覆盖的宽度
 * @param overrideHeight 覆盖的高度
 * @param errorPlaceholder 错误占位图
 * @param fallbackDrawable 回退占位图
 * @param placeholderDrawable 占位图
 * @param placeholderId 占位图资源 ID
 * @param errorId 错误图资源 ID
 * @param fallbackId 回退图资源 ID
 * @param isSkipMemoryCache 是否跳过内存缓存
 * @param useUnlimitedSourceGeneratorsPool 是否使用无限制的源生成器池
 * @param useAnimationPool 是否使用动画池
 * @param onlyRetrieveFromCache 是否仅从缓存加载
 * @param target 目标视图
 * @param requestListeners 请求监听器列表
 * @param requestCoordinator 请求协调器
 * @param engine 引擎
 * @param transitionOptions 过渡选项
 * @return SingleRequest 实例
 */
public static <R> SingleRequest<R> obtain(
        Context context,
        Glide glide,
        Object model,
        Key signature,
        Class<R> transcodeClass,
        Priority priority,
        DiskCacheStrategy diskCacheStrategy,
        Map<Class<?>, Transformation<?>> transformations,
        boolean isTransformationRequired,
        boolean isScaleOnlyOrNoTransform,
        Options options,
        int overrideWidth,
        int overrideHeight,
        Drawable errorPlaceholder,
        Drawable fallbackDrawable,
        Drawable placeholderDrawable,
        int placeholderId,
        int errorId,
        int fallbackId,
        boolean isSkipMemoryCache,
        boolean useUnlimitedSourceGeneratorsPool,
        boolean useAnimationPool,
        boolean onlyRetrieveFromCache,
        Target<R> target,
        List<RequestListener<R>> requestListeners,
        RequestCoordinator requestCoordinator,
        Engine engine,
        TransitionOptions<?, ? super R> transitionOptions) {
    // 从对象池中获取 SingleRequest 实例,如果没有则创建一个新的实例
    SingleRequest<R> request = (SingleRequest<R>) getRecycledOrCreate();
    request.init(
            context,
            glide,
            model,
            signature,
            transcodeClass,
            priority,
            diskCacheStrategy,
            transformations,
            isTransformationRequired,
            isScaleOnlyOrNoTransform,
            options,
            overrideWidth,
            overrideHeight,
            errorPlaceholder,
            fallbackDrawable,
            placeholderDrawable,
            placeholderId,
            errorId,
            fallbackId,
            isSkipMemoryCache,
            useUnlimitedSourceGeneratorsPool,
            useAnimationPool,
            onlyRetrieveFromCache,
            target,
            requestListeners,
            requestCoordinator,
            engine,
            transitionOptions);
    return request;
}

6.2.3 请求开始方法

java

java 复制代码
@Override
public void begin() {
    startTime = LogTime.getLogTime();
    if (model == null) {
        // 如果图片来源为空,根据是否有回退图进行处理
        if (Util.isValidOptions(requestOptions.getFallback())) {
            onLoadFailed(new GlideException("Received null model"), DataSource.LOCAL);
        } else {
            onLoadFailed(new GlideException("Received null model"), DataSource.LOCAL);
            target.onLoadStarted(getPlaceholderDrawable());
        }
        return;
    }

    if (status == Status.RUNNING) {
        // 如果请求已经在运行,直接返回
        return;
    }

    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        // 如果已经有有效的尺寸,开始加载资源
        status = Status.RUNNING;
        runLoad();
    } else {
        // 否则,等待获取尺寸
        status = Status.WAITING_FOR_SIZE;
        if (Util.isValidOptions(requestOptions.getPlaceholder())) {
            target.onLoadStarted(getPlaceholderDrawable());
        }
        target.getSize(this);
    }
}

private void runLoad() {
    status = Status.RUNNING;
    // 检查是否需要重置状态
    if (isComplete() || isFailed()) {
        reset();
    }
    // 获取请求的优先级
    Priority priority = getPriority();
    // 获取缓存键
    Key key = getKey();
    // 获取转换操作
    Map<Class<?>, Transformation<?>> appliedTransformations = getTransformations();
    // 获取缓存策略
    DiskCacheStrategy diskCacheStrategy = getDiskCacheStrategy();
    // 获取是否跳过内存缓存
    boolean isSkipMemoryCache = getSkipMemoryCache();
    // 获取是否仅从缓存加载
    boolean onlyRetrieveFromCache = getOnlyRetrieveFromCache();
    // 创建引擎作业
    engineJob = engine.load(
            context,
            model,
            key,
            signature,
            width,
            height,
            appliedTransformations,
            transcodeClass,
            priority,
            diskCacheStrategy,
            isSkipMemoryCache,
            onlyRetrieveFromCache,
            options,
            this);
}

begin 方法是请求开始的入口。首先记录开始时间,然后检查图片来源是否为空。如果为空,根据是否有回退图进行相应处理。接着检查请求状态,如果已经在运行则直接返回。如果已经有有效的尺寸,调用 runLoad 方法开始加载资源;否则,等待获取尺寸。

runLoad 方法会重置请求状态,获取请求的各种参数,如优先级、缓存键、转换操作、缓存策略等,然后调用 engine.load 方法开始真正的加载操作。

6.2.4 请求完成和失败处理方法

java

java 复制代码
@Override
public void onEngineJobComplete(EngineJob<?> engineJob, EngineResource<?> resource) {
    if (engineJob != this.engineJob) {
        // 如果不是当前请求的引擎作业,直接返回
        return;
    }

    this.engineJob = null;
    if (resource != null) {
        // 如果资源不为空,处理加载成功
        onResourceReady(resource.get(), DataSource.REMOTE);
    } else {
        // 否则,处理加载失败
        onLoadFailed(new GlideException("Load failed"), DataSource.REMOTE);
    }
}

@Override
public void onEngineJobCancelled(EngineJob<?> engineJob, Key key) {
    if (engineJob != this.engineJob) {
        // 如果不是当前请求的引擎作业,直接返回
        return;
    }
    // 处理引擎作业取消
    this.engineJob = null;
    status = Status.CLEARED;
    target.onLoadCleared(getPlaceholderDrawable());
}

private void onResourceReady(Resource<ResourceType> resource, DataSource dataSource) {
    this.resource = resource;
    status = Status.COMPLETE;
    // 创建过渡对象
    Transition<? super ResourceType> transition = transitionFactory.build(dataSource, isFirstResource());
    if (transition == null || !target.transition(transition)) {
        // 如果没有过渡效果或过渡失败,直接设置资源
        setResourceInternal(resource);
    } else {
        // 否则,开始过渡
        startTransition(transition);
    }
}

private void onLoadFailed(GlideException e, DataSource dataSource) {
    this.error = e;
    status = Status.FAILED;
    glide.getExecutor().execute(new LogRequestFailureRunnable(e, model, target, dataSource, /*isFirstResource=*/ true));
    // 显示错误占位图
    target.onLoadFailed(getErrorDrawable());
    for (RequestListener<ResourceType> listener : requestListeners) {
        // 通知请求监听器加载失败
        boolean handled = listener.onLoadFailed(e, model, target, dataSource);
        if (handled) {
            return;
        }

6.3 ThumbnailRequestCoordinator 类分析

6.3.1 类定义及属性

java

java 复制代码
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.RequestCoordinator;

// ThumbnailRequestCoordinator 类,用于协调主请求和缩略图请求
public class ThumbnailRequestCoordinator implements RequestCoordinator {
    // 缩略图请求
    private final Request thumbnailRequest;
    // 主请求
    private final Request mainRequest;
    // 父协调器
    private final RequestCoordinator parent;
    // 主请求是否已完成
    private boolean isMainComplete;
    // 缩略图请求是否已完成
    private boolean isThumbnailComplete;

    public ThumbnailRequestCoordinator(
            @NonNull Request thumbnailRequest,
            @NonNull Request mainRequest,
            @Nullable RequestCoordinator parent) {
        this.thumbnailRequest = thumbnailRequest;
        this.mainRequest = mainRequest;
        this.parent = parent;
    }
}

ThumbnailRequestCoordinator 类持有缩略图请求、主请求和父协调器的引用,同时维护了主请求和缩略图请求的完成状态。

6.3.2 请求协调方法

java

java 复制代码
@Override
public boolean canSetImage(Request request) {
    // 如果是缩略图请求,且主请求未完成,则允许设置图片
    if (request == thumbnailRequest) {
        return !isMainComplete;
    }
    // 如果是主请求,直接允许设置图片
    return true;
}

@Override
public boolean canNotifyStatusChanged(Request request) {
    // 如果是缩略图请求,且主请求未完成,则允许通知状态改变
    if (request == thumbnailRequest) {
        return !isMainComplete;
    }
    // 如果是主请求,直接允许通知状态改变
    return true;
}

@Override
public boolean canNotifyCleared(Request request) {
    // 如果有父协调器,调用父协调器的 canNotifyCleared 方法
    if (parent != null) {
        return parent.canNotifyCleared(request);
    }
    return true;
}

@Override
public boolean isAnyResourceSet() {
    // 如果主请求已完成或者缩略图请求已完成,则表示有资源已设置
    return isMainComplete || isThumbnailComplete;
}

@Override
public void onRequestSuccess(Request request) {
    if (request == mainRequest) {
        isMainComplete = true;
        // 主请求成功,清除缩略图请求
        thumbnailRequest.clear();
    } else if (request == thumbnailRequest) {
        isThumbnailComplete = true;
    }
    // 如果有父协调器,通知父协调器请求成功
    if (parent != null) {
        parent.onRequestSuccess(request);
    }
}

@Override
public void onRequestFailed(Request request) {
    if (request == mainRequest) {
        isMainComplete = true;
    } else if (request == thumbnailRequest) {
        isThumbnailComplete = true;
    }
    // 如果有父协调器,通知父协调器请求失败
    if (parent != null) {
        parent.onRequestFailed(request);
    }
}
  • canSetImage 方法:用于判断是否允许请求设置图片。对于缩略图请求,如果主请求还未完成,则允许设置;对于主请求,始终允许设置。
  • canNotifyStatusChanged 方法:用于判断是否允许请求通知状态改变,逻辑与 canSetImage 类似。
  • canNotifyCleared 方法:如果有父协调器,会调用父协调器的 canNotifyCleared 方法,否则直接允许通知清除。
  • isAnyResourceSet 方法:判断是否有任何请求的资源已设置,只要主请求或缩略图请求中有一个完成,就返回 true
  • onRequestSuccess 方法:当请求成功时,如果是主请求,标记主请求已完成并清除缩略图请求;如果是缩略图请求,标记缩略图请求已完成。同时,如果有父协调器,会通知父协调器请求成功。
  • onRequestFailed 方法:当请求失败时,标记相应请求已完成,并通知父协调器请求失败。

七、请求队列管理

7.1 RequestTracker 类分析

7.1.1 类定义及属性

java

java 复制代码
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.request.Request;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

// RequestTracker 类,用于跟踪和管理请求
public class RequestTracker {
    // 正在运行的请求列表
    private final List<Request> requests = new ArrayList<>();
    // 待添加的请求列表
    private final List<Request> pendingRequests = new ArrayList<>();
    // 是否暂停请求
    private boolean isPaused;

    public RequestTracker() {
        // 默认不暂停请求
        this.isPaused = false;
    }
}

RequestTracker 类负责跟踪和管理所有的请求,使用 requests 列表存储正在运行的请求,pendingRequests 列表存储待添加的请求,isPaused 标志表示请求是否处于暂停状态。

7.1.2 请求管理方法

java

java 复制代码
/**
 * 运行请求
 * 
 * @param request 请求对象
 */
public void runRequest(@NonNull Request request) {
    requests.add(request);
    if (!isPaused) {
        // 如果未暂停,开始请求
        request.begin();
    } else {
        // 否则,将请求添加到待处理列表
        pendingRequests.add(request);
    }
}

/**
 * 暂停请求
 */
public void pauseRequests() {
    isPaused = true;
    for (Request request : new ArrayList<>(requests)) {
        if (request.isRunning()) {
            // 暂停正在运行的请求
            request.pause();
            pendingRequests.add(request);
        }
    }
}

/**
 * 恢复请求
 */
public void resumeRequests() {
    isPaused = false;
    for (Request request : pendingRequests) {
        // 开始待处理的请求
        request.begin();
    }
    pendingRequests.clear();
}

/**
 * 清除请求
 * 
 * @param request 请求对象
 */
public void clearRequest(@NonNull Request request) {
    requests.remove(request);
    pendingRequests.remove(request);
    request.clear();
}

/**
 * 清除所有请求
 */
public void clearRequests() {
    for (Request request : new ArrayList<>(requests)) {
        clearRequest(request);
    }
    pendingRequests.clear();
}

/**
 * 判断是否有正在运行的请求
 * 
 * @return 是否有正在运行的请求
 */
public boolean isAnyRequestRunning() {
    for (Request request : requests) {
        if (request.isRunning()) {
            return true;
        }
    }
    return false;
}
  • runRequest 方法:将请求添加到 requests 列表中,如果请求未暂停,则立即开始请求;否则,将请求添加到 pendingRequests 列表中。
  • pauseRequests 方法:将 isPaused 标志设置为 true,暂停所有正在运行的请求,并将它们添加到 pendingRequests 列表中。
  • resumeRequests 方法:将 isPaused 标志设置为 false,开始 pendingRequests 列表中的所有请求,并清空该列表。
  • clearRequest 方法:从 requestspendingRequests 列表中移除请求,并清除请求。
  • clearRequests 方法:清除所有请求,包括正在运行的请求和待处理的请求。
  • isAnyRequestRunning 方法:遍历 requests 列表,判断是否有正在运行的请求。

八、请求构建与管理模块的性能优化和注意事项

8.1 性能优化建议

8.1.1 合理设置请求参数
  • 图片尺寸 :通过 override 方法明确指定图片的尺寸,避免 Glide 自动计算尺寸,减少不必要的内存消耗和图片处理时间。例如:

java

java 复制代码
Glide.with(context)
     .load(imageUrl)
     .override(200, 200)
     .into(imageView);
  • 缓存策略 :根据实际需求合理设置磁盘缓存策略。如果图片不经常变化,可以使用 DiskCacheStrategy.ALL 缓存原始数据和转换后的数据;如果图片经常更新,可以使用 DiskCacheStrategy.NONE 不进行磁盘缓存。例如:

java

java 复制代码
Glide.with(context)
     .load(imageUrl)
     .diskCacheStrategy(DiskCacheStrategy.ALL)
     .into(imageView);
8.1.2 避免重复请求

在发起请求前,检查目标视图上是否已经有相同的请求正在执行。可以通过 RequestisEquivalentTo 方法进行判断,如果请求相同且不需要跳过内存缓存,则不重新发起请求。例如,在 RequestBuilderinto 方法中就有这样的逻辑:

java

java 复制代码
Request request = buildRequest(target);
Request previous = target.getRequest();
if (request.isEquivalentTo(previous)
        && !isSkipMemoryCacheWithCompletePreviousRequest(previous)) {
    request.recycle();
    if (!Preconditions.checkNotNull(previous).isRunning()) {
        previous.begin();
    }
    return this;
}
8.1.3 优化请求队列管理

避免同时发起大量的请求,以免造成系统资源紧张。可以根据应用的实际情况,合理控制请求的并发数量。例如,可以通过自定义线程池来限制并发请求的数量:

java

java 复制代码
GlideExecutor executor = GlideExecutor.newFixedExecutor(3); // 最多同时执行 3 个请求
GlideBuilder builder = new GlideBuilder(context);
builder.setSourceExecutor(executor);
Glide glide = builder.build(context);

8.2 注意事项

8.2.1 内存泄漏问题
  • 生命周期管理 :确保 RequestManager 与 Activity 或 Fragment 的生命周期正确绑定,避免在 Activity 或 Fragment 销毁后仍然持有请求,导致内存泄漏。Glide 已经通过 RequestManagerLifecycle 机制解决了大部分生命周期管理问题,但在自定义 Target 时,需要特别注意在 onDestroy 方法中清除请求。
  • 静态引用 :避免在静态变量中持有 RequestManagerRequest 的引用,因为静态变量的生命周期与应用的生命周期相同,会导致引用的对象无法被垃圾回收。
8.2.2 异常处理

在请求过程中可能会出现各种异常,如网络异常、图片解码异常等。需要在 RequestListener 中对异常进行捕获和处理,避免应用崩溃。例如:

java

java 复制代码
Glide.with(context)
     .load(imageUrl)
     .listener(new RequestListener<Drawable>() {
         @Override
         public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
             // 处理加载失败的情况
             Log.e("Glide", "Image load failed: " + e.getMessage());
             return false;
         }

         @Override
         public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
             // 处理加载成功的情况
             return false;
         }
     })
     .into(imageView);
8.2.3 兼容性问题

不同版本的 Glide 可能会有一些 API 变化和行为差异,在升级 Glide 版本时,需要仔细阅读官方文档,确保代码的兼容性。同时,在不同的 Android 系统版本上,Glide 的表现可能会有所不同,需要进行充分的测试。

九、总结

Glide 的请求构建与管理模块是一个复杂而强大的系统,它通过 RequestBuilderRequestManagerRequestManagerRetrieverRequest 等核心组件,实现了图片加载请求的构建、参数设置、生命周期管理和队列调度等功能。开发者可以通过合理设置请求参数、优化请求队列管理和注意内存泄漏等问题,提高图片加载的性能和应用的稳定性。随着 Android 技术的不断发展,Glide 也在不断更新和优化,未来可能会提供更多强大的功能和更高效的性能。深入理解请求构建与管理模块的原理,有助于开发者更好地使用 Glide,为用户提供更优质的图片加载体验。

相关推荐
*星星之火*1 小时前
【GPT入门】第5课 思维链的提出与案例
android·gpt
EasyCVR2 小时前
EasyRTC嵌入式视频通话SDK的跨平台适配,构建web浏览器、Linux、ARM、安卓等终端的低延迟音视频通信
android·arm开发·网络协议·tcp/ip·音视频·webrtc
韩家老大2 小时前
RK Android14 在计算器内输入特定字符跳转到其他应用
android
张拭心4 小时前
2024 总结,我的停滞与觉醒
android·前端
夜晚中的人海4 小时前
【C语言】------ 实现扫雷游戏
android·c语言·游戏
ljx14000525506 小时前
Android AudioFlinger(一)——初识AndroidAudio Flinger
android
ljx14000525506 小时前
Android AudioFlinger(四)—— 揭开PlaybackThread面纱
android
Codingwiz_Joy6 小时前
Day04 模拟原生开发app过程 Androidstudio+逍遥模拟器
android·安全·web安全·安全性测试
叶羽西6 小时前
Android15 Camera框架中的StatusTracker
android·camera框架
梦中千秋6 小时前
安卓设备root检测与隐藏手段
android