Android Glide 3,王者笔记

  public void start() {
    // 状态置换跳过不看
    isStarted = true;
    resetLoopCount();
    if (isVisible) {
        // 真正的使能代码
        startRunning();
    }
}

private void startRunning() {
    // gif 只有 1 帧, 开始即结束
    if (decoder.getFrameCount() == 1) {
        // 通知界面重绘自己, 结束了
        invalidateSelf();
    } 
    
    // 不只 1 帧
    else if (!isRunning) {
        isRunning = true;
        // frameLoader 开始工作啦
        frameLoader.start();
        // 通知界面重绘自己, 就是把当前帧给先画出来
        invalidateSelf();
    }
} 

至此, 我们触发了 `frameLoader.start()` , 并且界面上目前也因为 `invalidateSelf()` 而绘制上了第一帧 再来看看第三步: 循环加载帧, 并渲染到界面上

*   **`GifFrameLoader` 依赖 `GifDecoder` 加载完成下一帧通知 `GifDrawable` 刷新视图**

// GifFrameLoader

public void start() {
    if (isRunning) {
        return;
    }
    isRunning = true;
    isCleared = false;
    
    // 上面都是些状态信息, 跳过不看, 这个函数看名字就知道跑去加载下一帧了
    loadNextFrame();
}

private void loadNextFrame() {
    if (!isRunning || isLoadPending) {
        return;
    }
    isLoadPending = true;
    
    // 这行是移动 gifDecoder 的解析位置, 跳到下一帧的位置
    gifDecoder.advance();
    // 获取下一帧的延时时间(gif 每帧之间都有个时间间隔)
    long targetTime = SystemClock.uptimeMillis() + gifDecoder.getNextDelay();
    DelayTarget next = new DelayTarget(handler, gifDecoder.getCurrentFrameIndex(), targetTime);
    // 开始异步加载, 即不在主线程执行加载程序
    requestBuilder
            .signature(new FrameSignature())
            .into(next);
} 

直接触发 `loadNextFrame()` 去加载下一帧, 真正的代码则是

*   `gifDecoder.advance()` 可以粗略理解成跳到下一帧头部位置
*   `gifDecoder.getNextDelay()` 获得下一帧的间隔时间
*   `requestBuilder.into()` 异步解析下一帧, 解析完成会回调 `DelayTarget`

下面看看 `DelayTarget` 里面的回调

// DelayTarget

public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
        this.resource = resource;
        // 解析完成了, resource就存储着下一帧的图
        Message msg = handler.obtainMessage(FrameLoaderCallback.MSG_DELAY, this);
        // 这里 MSG_DELAY 明显是处理帧的时间间隔, 现在要异步切回主线程处理刷新问题了
        handler.sendMessageAtTime(msg, targetTime);
}

private class FrameLoaderCallback implements Handler.Callback {
    public static final int MSG_DELAY = 1;
    public static final int MSG_CLEAR = 2;

    @Override
    public boolean handleMessage(Message msg) {
        if (msg.what == MSG_DELAY) {
            GifFrameLoader.DelayTarget target = (DelayTarget) msg.obj;
            // 继续追踪
            onFrameReady(target);
            return true;
        } else if (msg.what == MSG_CLEAR) {
            GifFrameLoader.DelayTarget target = (DelayTarget) msg.obj;
            Glide.clear(target);
        }
        return false;
    }
}

// GifFrameLoader

void onFrameReady(DelayTarget delayTarget) {
    if (isCleared) {
        handler.obtainMessage(FrameLoaderCallback.MSG_CLEAR, delayTarget).sendToTarget();
        return;
    }

    DelayTarget previous = current;
    current = delayTarget;
    // callback 是一个 GlideDrawable, 告诉它我帮你把下一帧加载出来了, 下面来看看 GlideDrawable 是如何做的
    callback.onFrameReady(delayTarget.index);

    if (previous != null) {

Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码
网盘:pan.baidu.com/s/12WbFc8cmVXhdgFkOLEfS5g
提取码:wecw (复制链接至浏览器打开)

最后

给大家送上我成功跳槽复习中所整理的资料,由于文章篇幅有限,所以只是把题目列出来了

**[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](

)**

Android Glide 3,王者笔记

Android Glide 3,王者笔记

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](

)**

[外链图片转存中…(img-ml23uPvF-1631443942355)]

[外链图片转存中…(img-KumgyJKG-1631443942356)]

Android Glide 3,王者笔记

上一篇:一手遮天 Android - view(媒体类): Glide 基础


下一篇:更改glide 缓存地址