Glide源码解析05-onLoadComplete

本文深入解析Glide中图片加载成功的流程,从EngineRunnable#onLoadComplete开始,通过Handler发送消息,EngineJob处理主线程结果,最终调用ImageViewTarget#onResourceReady完成图片展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Glide源码解析05-onLoadComplete

在Glide源码解析03中我们以及看到Glide调用了EngineRunnable#onLoadFailed或者EngineRunnable#onLoadComplete来调用失败或成功的结果。
这里我们来详细看下onLoadComplete,onLoadFailed也是同样的逻辑。

    if (resource == null) {
        onLoadFailed(exception);
    } else {
        onLoadComplete(resource);
    }
5.0 Handler.obtainMessage(MSG_COMPLETE)

在onLoadComplete中调用了EngineRunnableManager#onResourceReady(),其内部调用Handler发送了MSG_COMPLETE的消息。

public void onResourceReady(final Resource<?> resource) {
    this.resource = resource;
    MAIN_THREAD_HANDLER.obtainMessage(MSG_COMPLETE, this).sendToTarget();
}  
5.1 Handler.handleMessage

在handleMessage中,调用了EngineJob#handleResultOnMainThread()

public boolean handleMessage(Message message) {
    if (MSG_COMPLETE == message.what || MSG_EXCEPTION == message.what) {
        EngineJob job = (EngineJob) message.obj;
        if (MSG_COMPLETE == message.what) {
            job.handleResultOnMainThread();
        } else {
            job.handleExceptionOnMainThread();
        }
        return true;
    }

    return false;
}
5.2 EngineJob#handleResultOnMainThread

在这里,会去遍历ResourceCallback集合,并调用其onResourceReady(),这里的cb是GenericRequest对象。

private void handleResultOnMainThread() {
    //...

    for (ResourceCallback cb : cbs) {
        if (!isInIgnoredCallbacks(cb)) {
            engineResource.acquire();
            cb.onResourceReady(engineResource);
        }
    }
    //...
}
5.3 GenericRequest#onResourceReady ####

在这里会去调用target#onResourceReady(),target可以是ImageViewTarget的子类GlideDrawableImageViewTarget、DrawableImageViewTarget、BitmapImageViewTarget。
具体构建的地方在Glide电泳into方法时,使用ImageViewTargetFactory.buildTarget创建的target对象。

public void onResourceReady(Resource<?> resource) {
    //...
    onResourceReady(resource, (R) received);
}

private void onResourceReady(Resource<?> resource, R result) {
    boolean isFirstResource = isFirstReadyResource();
    status = Status.COMPLETE;
    this.resource = resource;

    if (requestListener == null || !requestListener.onResourceReady(result, model, target, loadedFromMemoryCache,
            isFirstResource)) {
        GlideAnimation<R> animation = animationFactory.build(loadedFromMemoryCache, isFirstResource);
        target.onResourceReady(result, animation);
    }

    notifyLoadSuccess();
    //...
}
5.4 ImageViewTarget#onResourceReady

ImageViewTarget的子类,调用onResourceReady时,最终都会调用setResource(),比如DrawableImageViewTarget

public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {
    public DrawableImageViewTarget(ImageView view) {
        super(view); //父类调用了setResource方法
    }

    @Override
    protected void setResource(Drawable resource) {
       view.setImageDrawable(resource);
    }
}

至此,图片加载成功。

PS:cb.onResourceReady

在5.2中,调用的cb.onResourceReady,cb为什么是GenericRequest对象对象呢? 这要看调用GenericRequest#onSizeReady()的时候

//GenericRequest#onSizeReady()
public void onSizeReady(int width, int height) {
    //...
    loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,
            priority, isMemoryCacheable, diskCacheStrategy, this);
    loadedFromMemoryCache = resource != null;
    //...
}

//Engine#load()  
public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
        DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
        Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
    //...

    EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
    //...
    EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
    jobs.put(key, engineJob);

    //将cb添加到EngineJob中,而cb就是GenericRequest调用engine.load时传入的this参数。
    engineJob.addCallback(cb);
    engineJob.start(runnable);

    return new LoadStatus(cb, engineJob);
}

更多

Glide源码解析01-with
Glide源码解析02-load
Glide源码解析03-into
Glide源码解析04-decode
Glide源码解析05-onLoadComplete
Glide源码解析06-Glide流程图

### Glide 源码解析 Glide 是一种功能强大的 Android 图片加载库,其设计目标是简化开发者在应用程序中加载、缓存和显示图像的过程。为了深入理解 Glide源码结构及其工作原理,可以从以下几个方面展开: #### 1. **核心类与模块** Glide 的架构由多个核心组件组成,主要包括 `RequestManager`、`Engine` 和 `ModelLoader` 等。 - **RequestManager**: 负责管理请求生命周期并提供接口供外部调用[^2]。通过 `with()` 方法创建实例,并绑定到特定上下文中。 - **Engine**: 执行实际的图片加载任务,负责协调缓存策略以及解码操作[^5]。它内部实现了三级缓存机制(内存缓存 -> 数据缓存 -> 网络加载)。 - **ModelLoader**: 定义如何将模型对象转换为目标数据流(如文件路径转为输入流)。例如,在加载 GIF 动态图时会使用专门的 ModelLoader 实现[^3]。 #### 2. **加载流程剖析** 当调用如下代码片段时: ```java Glide.with(context) .load(url) .into(imageView); ``` 以下是具体执行过程概述: ##### (1)构建 Request 对象 通过 `SingleRequest.obtain()` 创建单次请求实例,并设置必要参数(如 URL 地址、ImageView 组件等)[^5]。 ##### (2)触发 Engine 加载逻辑 进入 `engine.load()` 方法后,首先检查是否存在匹配键值对的快速命中情况;如果未发现,则进一步尝试从磁盘或其他存储位置检索资源副本[^5]。 ##### (3)启动 Decode Job 一旦确认需发起新作业或者等待已有任务完成,便会调用 `waitForExistingOrStartNewJob()` 函数开启异步线程池调度模式下的 decode 工作。 ##### (4)逐级查找合适 Generator 按照预定义优先级顺序依次测试三种可能的数据生产者——即 ResourceGenerator、DataCacheGenerator 及 SourceGenerator 是否满足当前需求。对于后者而言,还需借助对应的 ModelLoader 来获取远程服务器上的原始素材内容。 #### 3. **缓存机制详解** 正如前面提到过的那样,Glide 支持三层次级别的高速缓冲方案以提升性能表现: - **Memory Cache (Active Resources)**: 使用 HashMap 存储经过加工后的最终呈现形式(Bitmap 或 Drawable 类型),便于即时复用而无需重复计算开销; - **Disk Cache**: 利用 LRU 算法管理有限空间内的持久化记录集合,从而减少频繁网络交互带来的延迟影响; - **Source Data Cache**: 针对尚未被完全转化的目标材料实施暂存措施,以便后续阶段可直接读取而非重新拉取全部资料[^5]。 --- ### 示例代码展示 以下是一个简单的自定义配置案例演示如何调整默认行为: ```java // 设置全局选项 new GlideBuilder(applicationContext) .setLogLevel(Log.ERROR) // 修改日志级别 .setDefaultRequestOptions( new RequestOptions() .placeholder(R.drawable.placeholder_image) .error(R.drawable.error_image)) .build(); // 局部覆盖部分属性 GlideApp.with(context) .asGif() // 明确指明期望返回格式为动画类型 .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)) // 强制启用全面缓存策略 .load(gifUrl) .listener(new RequestListener<GifDrawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) { Log.e("Glide", "Error loading gif!", e); return false; } @Override public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) { Log.d("Glide", "Successfully loaded gif!"); return false; } }) .into(imageView); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

氦客

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值