0
点赞
收藏
分享

微信扫一扫

Glide 图片库原理(二)

Glide 吐槽

源码太多了,状态机对于阅读源码来说是个苦力活,而且必须借助工具完成,推荐脑图

简化一个整个流程图

with, load ,into

into 代码巨大,先上流程图

Glide.width 流程图

into 流程图

由于代码流程太多,所以建议下载图片放大看细节。

或者跟着脑图走--->Github docs 放在vscode 插件中查看

分析源码思路,

第一大步:只管主线 简单的走通 不要管支线
第二大步:重点在主线,稍微瞄一眼支线
第三大步:稍微分析支线,回顾主线
第四大步:分析支线细节,回顾主线
第五大步:分析支线细节,来寻找答案

0.项目中大量的使用了Glide,偶尔会出现内存溢出问题,请说说大概是什么原因?
答:尽量在with的时候,传入有生命周期的作用域(非Application作用域),尽量避免使用了Application作用域,因为Application作用域不会对页面绑定生命周期机制,就回收不及时释放操作等....

1.使用Glide为什么要加入网络权限? <uses-permission android:name="android.permission.INTERNET" />
答:等待队列/运行队列 执行Request ---> 活动缓存 --->内存缓存 ---> jobs.get检测执行的任务有没有执行完成 ---> HttpUrlFetcher.HttpURLConnection

2.使用Glide时,with函数在子线程中,会有什么问题?
答:子线程,不会去添加 生命周期机制, 主线程才会添加 空白的Fragment 去监听 Activity Fragment 的变化。

3.使用Glide时,with函数传入Application后,Glide内部会怎么处理?
答:在MainActivity中,MainActivity销毁了,并会让Glide生命周期机制处理回收,只有在整个APP应用都没有的时候,跟随着销毁(上节课 ApplicationLIfecycle add onStart onDestroy 什么事情都没有做)。

4.Glide源码里面的缓存,为什么要有 活动缓存 还需要 有内存缓存?
答:
因为LRU内存缓存添加满的时候,刚好访问最少使用那个A,如果LRU在添加数据,那么就会移除A,但是界面正在用A,那么就会导致崩溃。为了解决这种问题,所以添加了活动缓存。
把正在使用的放在活动缓存中,并且是非LRU的缓存。

分析步骤

第一步:【with
public RequestManager get(@NonNull FragmentActivity activity) {
if (Util.isOnBackgroundThread()) {
// Application 作用域
} else {
// 非Application 作用域
}
}

第二步:【load】
最终返回:RequestBuilder

第三步:【into】 看源码的思路,如果遇到接口怎么办? 前面必须 埋下伏笔

1. ImageViewTarget(显示图片) 无论走多远多远,最终一定回到这里ImageViewTarget 埋下伏笔
return into(
glideContext.buildImageViewTarget(view, transcodeClass), ImageViewTarget
);

2. Request request = new SingleRequest 埋下伏笔

3. SingleRequest public void begin() {...}


4. if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
onSizeReady(overrideWidth, overrideHeight); 用户设置 宽和高
} else {
target.getSize(this); 用户没有设置 宽和高 再次测量 -----> onSizeReady
}

5. memoryResource = loadFromMemory(key, isMemoryCacheable, startTime); 活动缓存 内存缓存
if (memoryResource == null) {
缓存没有
}
cb.onResourceReady(memoryResource, DataSource.MEMORY_CACHE); 命中缓存 回调去显示了


6. EngineJob<?> current = jobs.get(key, onlyRetrieveFromCache); 查找有没有正在运行的任务


7. EngineJob线程池大管家 DecodeJob执行的任务

8. currentGenerator = getNextGenerator(); SourceGenerator 埋下伏笔

9. SourceGenerator 分析 LoadData<Data> buildLoadData 没有埋下伏笔 Glide预习资料(构造函数 注册机)
.append(GlideUrl.class, InputStream.class, new HttpGlideUrlLoader.Factory()) Glide 注册机 埋下了伏笔

List<LoadData<?>> getLoadData() == HttpGlideUrlLoader {目标HttpUrlFetcher}

最终返回:HttpUrlFetcher 终于找到了 网络访问的地方 HttpUrlConn 来得到 InputStream

10 public Resource<Transcode> decode(
{
// InputStream ---> Bitmap == decoded
Resource<ResourceType> decoded = decodeResource(rewinder, width, height, options
)
;
Resource<ResourceType> transformed = callback.onResourceDecoded(decoded); // 回调回去
return transcoder.transcode(transformed, options);
}
举报

相关推荐

0 条评论