ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android Glide 3,王者笔记

2021-09-12 19:02:29  阅读:234  来源: 互联网

标签:Glide 一帧 王者 gifDecoder public MSG msg Android DelayTarget


  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学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](

)**

image

image

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

)**

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

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

image

标签:Glide,一帧,王者,gifDecoder,public,MSG,msg,Android,DelayTarget
来源: https://blog.csdn.net/m0_61549556/article/details/120254253

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有