美文网首页Android进阶之路
【建议收藏】面试没亮点?给你一份Android热门三方库源码面试

【建议收藏】面试没亮点?给你一份Android热门三方库源码面试

作者: 码了个码农 | 来源:发表于2020-12-10 11:51 被阅读0次

    前言

    众所周知,优秀源码的阅读与理解是最能提升自身功力的途径,如果想要成为一名优秀的Android工程师,那么Android中优秀三方库源码的分析和理解则是必备技能。就拿比较热门的图片加载框架Glide来说,相信很多同学都使用过,那么,当别人问你下面这些问题时你是否能回答出来呢?(Glide五连发)

    • 1、为什么要在项目中使用这个库?
    • 2、这个库都有哪些用法?对应什么样的使用场景?
    • 3、这个库的核心实现原理是什么?如果让你实现这个库的某些核心功能,你会考虑怎么去实现?
    • 4、Glide源码机制的核心思想是什么?
    • 5、Glide中是如何计算一张图片的大小的?

    相信能全部回答出来的同学并不多,下面我来解答一下上面几个问题。

    1、为什么要在项目中使用这个库?

    • 1、多样化媒体加载:不仅可以进行图片缓存,还支持Gif、WebP、缩略图,甚至是Video。
    • 2、通过设置绑定生命周期:可以使加载图片的生命周期动态管理起来。
    • 3、高效的缓存策略:支持内存、Disk缓存,并且Picasso只会缓存原始尺寸的图片,而Glide缓存的是多种规格,也就是Glide会根据你ImageView的大小来缓存相应大小的图片尺寸。
    • 4、内存开销小:我们可以手动配置默认的Bitmap解码格式为 RGB_565格式,以减少图片占用的内存开销。

    2、这个库都有哪些用法?对应什么样的使用场景?

    • 1、图片加载:Glide.with(this).load(imageUrl).override(800, 800).placeholder().error().animate().into()。
    • 2、多样式媒体加载:asBitamp、asGif。
    • 3、生命周期集成。
    • 4、可以配置磁盘缓存策略ALL、NONE、SOURCE、RESULT。

    3、这个库的核心实现原理是什么?如果让你实现这个库的某些核心功能,你会考虑怎么去实现?

    要想了解Glide的核心实现原理,就必须先从它的加载API Glide.with().into()来进行分析。

    1、Glide&with:

    • 1、初始化各式各样的配置信息(包括缓存,请求线程池,大小,图片格式等等)以及glide对象。
    • 2、将glide请求和application/SupportFragment/Fragment的生命周期绑定在一块。

    2、Glide&load:

    设置请求url,并记录url已设置的状态。

    3、Glide&into:

    • 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 与dex2oat
    2、热修复常见问题之CLASS_ISPREVERIFIED 问题
    3、热修复原理
    4、Tinker 的集成与使用(自动补丁包生成)


    image image

    第二章:插件化

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


    image image

    三:组件化框架设计

    1、阿里巴巴开源路由框——ARouter 原理分析
    2、APT 编译时期自动生成代码&动态类加载
    3、Java SPI 机制
    4、AOP&IOC
    5、手写组件化架构


    image image

    四、图片加载框架

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


    image

    五、网络请求框架

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


    image

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

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


    image

    七、IOC 架构设计

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


    image

    八、Android架构组件Jetpack

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


    image

    由于篇幅原因,需要完整PDF文档的朋友可以点击这里直达领取

    相关文章

      网友评论

        本文标题:【建议收藏】面试没亮点?给你一份Android热门三方库源码面试

        本文链接:https://www.haomeiwen.com/subject/evblgktx.html