前言
成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~。
众所周知,优秀源码的阅读与理解是最能提升自身功力的途径,如果想要成为一名优秀的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热门三方库源码面试宝典
因此,为了将热门三方库涉及的知识成体系地融合起来,笔者创建了Awesome-Third-Library-Source-Analysis这个项目,为的就是让每一个Android工程师能够从以下七个方面全方位地提升自己的技术实力。
项目地址:Awesome-Third-Library-Source-Analysis
深入理解热门三方库实现原理,从七个角度全方位提升你的功力~
Contents
网络
- OkHttp (已完成)
Android最优秀的网络底层框架,没有之一。
- Retrofit (已完成)
Android最优秀的网络封装框架,内含九种常用设计模式的灵活运用。
图片
- Glide (已完成)
Android使用最广泛的图片加载框架。
数据库
- GreenDao (已完成)
Android中数据库操作综合效率最高的框架。
响应式编程
- RxJava (已完成)
来一起探究RxJava的异步、简洁、优雅和它强大的操作符吧!
内存泄露
- LeakCanary (已完成)
LeakCanary究竟是如何检测出内存泄露的呢?
依赖注入
- ButterKnife(已完成)
使用APT + 注解攻破了findViewByid(),JW大神之作。
- Dagger2(已完成)
Dagger就一把匕首,在中大型项目中,它能提升开发效率、自动管理类的实例、解耦,是如此的干脆。
事件总线
- EventBus(已完成)
使用扩展的观察者模式实现的组件间通信框架,广播的替代者。
Contact Me
现如今,Android 行业人才已逐渐饱和化,但高级人才依旧很稀缺,我们经常遇到的情况是,100份简历里只有2、3个比较合适的候选人,大部分的人都是疲于业务,没有花时间来好好学习,或是完全不知道学什么来提高自己的技术。对于 Android 开发者来说,尽早建立起一个完整的 Android 知识框架,了解目前大厂高频出现的常考知识点,掌握面试技巧,是一件非常需要重视的事情。
去年,为了进入一线大厂去做更有挑战的事情,拿到更高的薪资,我提前准备了半年的时间,沉淀了一份 「两年磨一剑」 的体系化精品面试题,而后的半年,我都在不断地进行面试,总共面试了二三十家公司,每一场面试完之后,我都将对应的面试题和详细的答案进行了系统化的总结,并更新到了我的面试项目里,现在,在每一个模块之下,我都已经精心整理出了 超高频和高频的常考 知识点。
在我近一年的大厂实战面试复盘中逐渐对原本的内容进行了大幅度的优化,并且新增了很多新的内容。它可以说是一线互联网大厂的面试精华总结,同时后续还会包含如何写简历和面试技巧的内容,能够帮你省时省力地准备面试,大大降低找到一个好工作的难度。
这份面试项目不同于我 Github 上的 Awesome-Android-Interview 面试项目:github.com/JsonChao/Aw… 已经在 2 年前(2020年 10 月停止更新),内容稍显陈旧,里面也有不少点表述不严谨,总体含金量较低。而我今天要分享的这份面试题库,是我在这两年持续总结、细化、沉淀出来的体系化精品面试题,里面很多的核心题答案在面试的压力下,经过了反复的校正与升华,含金量极高。
在分享之前,有一点要注意的是,一定不要将资料泄露出去!细想一下就明白了:
1、如果暴露出去,拿到手的人比你更快掌握,更早进入大厂,拿到高薪,你进大厂的机会就会变小,毕竟现在好公司就那么多,一个萝卜一个坑。
2、两年前我公开分享的简陋版 Awesome-Android-Interview 面试题库现在还在被各个培训机构当做引流资料,加大了现在 Android 内卷。。
所以,这一点一定要切记。
现在,我已经在我的成长社群里修订好了 《体系化高频核心 Android 面试题库》 中的 ”计算机基础高频核心面试题“ 和 ”Java 和 kotlin 高频核心面试题“ 部分,后续还会为你带来我核心题库中的:
- “Android基础 高频核心面试题”
- “基础架构 高频核心面试题”
- “跨平台 高频核心面试题”
- “性能优化 高频核心面试题”
- ”Framework 高频核心面试题“
- ”NDK 高频核心面试题“
获取方法:点击此处查看。
出身普通的人,如何真正改变命运?
这是我过去五、六年一直研究的命题。首先,是为自己研究,因为我是从小城镇出来的,通过持续不断地逆袭立足深圳。越是出身普通的人,就越需要有耐心,去进行系统性地全面提升,这方面,我有非常丰富的实践经验和方法论。因此,我开启了 “JsonChao” 的成长社群,希望和你一起完成系统性地蜕变。
星球目前有哪些服务?
- 每周会提供一份让 个人增值,避免踩坑 的硬干货。
- 每日以文字或语音的形式分享我个人学习和实践中的 思考精华或复盘记录。
- 提供 每月 三 次成长、技术或面试指导的咨询服务。
- 更多服务正在研发中…
超哥的知识星球适合谁?
- 如果你希望持续提升自己,获得更高的薪资或是想加入大厂,那么超哥的知识星球会对你有很大的帮助。
- 如果你既努力,又焦虑,特别适合加入超哥的知识星球,因为我经历过同样的阶段,而且最后找到了走出焦虑,靠近梦想的地方。
- 如果你希望改变自己的生活状态,欢迎加入超哥的知识星球,和我一起每日迭代,持续精进。
星球如何定价?
365元每年
每天一元,给自己的成长持续加油💪
为了回馈 JsonChao 的 掘金 忠实用户,我申请了少量优惠券,先到者先得,错过再无。
今天的文章【建议收藏】面试没有亮点?给你一份Android热门三方库源码面试宝典分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19703.html