Android Glide 3

float drawableRatio = resource.getIntrinsicWidth() / (float) resource.getIntrinsicHeight();
if (Math.abs(viewRatio - 1f) <= SQUARE_RATIO_MARGIN
&& Math.abs(drawableRatio - 1f) <= SQUARE_RATIO_MARGIN) {
resource = new SquaringDrawable(resource, view.getWidth());
}
}
super.onResourceReady(resource, animation);
this.resource = resource;
// 这里调用了 GifDrawable 的 start 方法
resource.setLoopCount(maxLoopCount);
resource.start();
}

// GlideDrawable

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) {
handler.obtainMessage(FrameLoaderCallback.MSG_CLEAR, previous).sendToTarget();
}

isLoadPending = false;
loadNextFrame();
}

  • DelayTarget.onResourceReady() 加载下一帧完成了;
  • handler.sendMessageAtTime 切回主线程, 顺便还把 帧的时间间隔问题解决了
  • callback.onFrameReady() 通知 callback 也就是 GlideDrawable 加载好了

下面来看看 GlideDrawable 在被通知加载好了之后做了些啥

// GlideDrawable

public void onFrameReady(int frameIndex) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB && getCallback() == null) {
stop();
reset();
return;
}

// 刷新自己, 触发 draw() 方法
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

尾声

以薪资待遇为基础,以发展为最终目标,要在高薪资的地方,谋求最好的发展!

下面是有几位Android行业大佬对应上方技术点整理的一些进阶资料。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

id行业大佬对应上方技术点整理的一些进阶资料。

[外链图片转存中…(img-6fgXSdot-1713714654884)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值