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学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](
)**
[外链图片转存中…(img-ml23uPvF-1631443942355)]
[外链图片转存中…(img-KumgyJKG-1631443942356)]
标签:Glide,一帧,王者,gifDecoder,public,MSG,msg,Android,DelayTarget 来源: https://blog.csdn.net/m0_61549556/article/details/120254253