写点什么

【建议收藏】面试没亮点?给你一份 Android 热门三方库源码面试宝典及学习笔记

用户头像
Android架构
关注
发布于: 2021 年 11 月 07 日
  • 1、首先根据转码类 transcodeClass 类型返回不同的 ImageViewTarget:BitmapImageViewTarget、DrawableImageViewTarget。

  • 2、递归建立缩略图请求,没有缩略图请求,则直接进行正常请求。

  • 3、如果没指定宽高,会根据 ImageView 的宽高计算出图片宽高,最终执行到 onSizeReay()方法中的 engine.load()方法。

  • 4、engine 是一个负责加载和管理缓存资源的类


其中 Glide 的三层缓存机制是值得我们去反复学习揣摩的,这里我们先了解下常规的三级缓存是怎样的。

常规三级缓存的流程:强引用->软引用->硬盘缓存

当我们的 APP 中想要加载某张图片时,先去 LruCache 中寻找图片,如果 LruCache 中有,则直接取出来使用,如果 LruCache 中没有,则去 SoftReference 中寻找(软引用适合当 cache,当内存吃紧的时候才会被回收。而 weakReference 在每次 system.gc()就会被回收)(当 LruCache 存储紧张时,会把最近最少使用的数据放到 SoftReference 中),如果 SoftReference 中有,则从 SoftReference 中取出图片使用,同时将图片重新放回到 LruCache 中,如果 SoftReference 中也没有图片,则去硬盘缓存中中寻找,如果有则取出来使用,同时将图片添加到 LruCache 中,如果没有,则连接网络从网上下载图片。图片下载完成后,将图片保存到硬盘缓存中,然后放到 LruCache 中。

Glide 的三层缓存机制

Glide 缓存机制大致分为三层:弱引用缓存、内存缓存、磁盘缓存。


  • 取的顺序是:弱引用、内存、磁盘。

  • 存的顺序是:弱引用、内存、磁盘。


三层存储的机制在 Engine 中实现的。先说下 Engine 是什么?Engine 这一层负责加载时做管理内存缓存的逻辑。持有 MemoryCache、Map<Key, WeakReference<EngineResource<?>>>。通过 load()来加载图片,加载前后会做内存存储的逻辑。如果内存缓存中没有,那么才会使用 EngineJob 这一层来进行异步获取硬盘资源或网络资源。EngineJob 类似一个异步线程或 observable。Engine 是一个全局唯一的,通过 Glide.getEngine()来获取。


需要一个图片资源,如果 Lrucache 中有相应的资源图片,那么就返回,同时从 Lrucache 中清除,放到 activeResources 中。activeResources map 是盛放正在使用的资源,以弱引用的形式存在。同时资源内部有被引用的记录。如果资源没有引用记录了,那么再放回 Lrucache 中,同时从 activeResources 中清除。如果 Lrucache 中没有,就从 activeResources 中找,找到后相应资源引用加 1。如果 Lrucache 和 activeResources 中没有,那么进行资源异步请求(网络/diskLrucache),请求成功后,资源放到 diskLrucache 和 activeResources 中。

4、Glide 源码机制的核心思想:

使用一个弱引用 map activeResources 来盛放项目中正在使用的资源。Lrucache 中不含有正在使用的资源。资源内部有个计数器来显示自己是不是还有被引用的情况,把正在使用的资源和没有被使用的资源分开有什么好处呢??因为当 Lrucache 需要移除一个缓存时,会调用 resource.recycle()方法。注意到该方法上面注释写着只有没有任何 consumer 引用该资源的时候才可以调用这个方法。那么为什么调用 resource.recycle()方法需要保证该资源没有任何 consumer 引用呢?glide 中 resource 定义的 recycle()要做的事情是把这个不用的资源(假设是 bitmap 或 drawable)放到 bitmapPool 中。bitmapPool 是一个 bitmap 回收再利用的库,在做 transform 的时候会从这个 bitmapPool 中拿一个 bitmap 进行再利用。这样就避免了重新创建 bitmap,减少了内存的开支。而既然 bitmapPool 中的 bitmap 会被重复利用,那么肯定要保证回收该资源的时候(即调用资源的 recycle()时),要保证该资源真的没有外界引用了。这也是为什么 glide 花费那么多逻辑来保证 Lrucache 中的资源没有外界引用的原因。

5、Glide 中是如何计算一张图片的大小的?

图片占用内存的计算公式:图片高度 * 图片宽度 * 一个像素占用的内存大小。所以,计算图片占用内存大小的时候,要考虑图片所在的目录跟设备密度,这两个因素其实影响的是图片的宽高,android 会对图片进行拉升跟压缩。


上面笔者只是简单地讲解一下下 Glide 的内部实现机制,但是这是远远不够的,如果想要对 Glide 或其它热门三方库有足够具象地了解,就必须深入源码去感受其中的艺术

助力一份 Android 热门三方库源码面试宝典

因此,为了将热门三方库涉及的知识成体系地融合起来,笔者花了将近半个月时间将 Android 热修复框架、插件化框架、组件化框架、图片加载框架、网络访问框架、RxJava 响应式编程框架、IOC 依赖注入框架、最近架构组件 Jetpack 等等 Android 第三方开源框架整合成了一套系统知识笔记 PDF,长达 1042 页!相信看完这份文档,你将会对这些 Android 第三方框架有着更深入、更系统的理解。

第一章:热修复

1、AOT/JIT & dexopt 与 dex2oat2、热修复常见问题之 CLASS_ISPREVERIFIED 问题 3、热修复原理 4、Tinker 的集成与使用(自动补丁包生成)



第二章:插件化

1、Class 文件与 Dex 文件的结构解读 2、Android 资源加载机制详解 3、四大组件调用原理 4、so 文件加载机制 5、Android 系统服务实现原理



三:组件化框架设计

1、阿里巴巴开源路由框——ARouter 原理分析 2、APT 编译时期自动生成代码 &动态类加载 3、Java SPI 机制 4、AOP&IOC5、手写组件化架构![image](https://upload-images.jianshu.io/upload_images/25267696-02e52b90c2687504.png?imageMogr2/auto-orient/strip%7Cim


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ageView2/2/w/1240)


四、图片加载框架

1、图片加载框架选型 2、Glide 原理分析 3、手写图片加载框架实战


五、网络请求框架

1、网络通信必备基础 2、OkHttp 源码解读


六、RXJava 响应式编程框架设计

1、链式调用 2、扩展的观察者模式 3、事件变换设计 4、Scheduler 线程控制


七、IOC 架构设计

1、依赖注入与控制反转 2、ButterKnife 原理 3、Dagger 架构设计核心解密


八、Android 架构组件 Jetpack

1、LiveData 工作原理 2、Navigation 如何解决 tabLayout 问题 3、ViewModel 如何感知 view 生命周期及内核原理 4、Room 架构方式方法 5、DataBinding 为什么支持 MVVM?6、WorkManager 内核解密 7、Lifecycles 生命周期



用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
【建议收藏】面试没亮点?给你一份Android热门三方库源码面试宝典及学习笔记