众所周知,优秀源码的阅读与理解是最能提高自身功力的途径,若是想要成为一名优秀的Android工程师,那么Android中优秀三方库源码的分析和理解则是必备技能。就拿比较热门的图片加载框架Glide来讲,相信不少同窗都使用过,那么,当别人问你下面这些问题时你是否能回答出来呢?(Glide五连发)android
相信能所有回答出来的同窗并很少,下面我来解答一下上面几个问题。git
要想了解Glide的核心实现原理,就必须先从它的加载API Glide.with().into()来进行分析。github
设置请求url,并记录url已设置的状态。面试
其中Glide的三层缓存机制是值得咱们去反复学习揣摩的,这里咱们先了解下常规的三级缓存是怎样的。数据库
当咱们的APP中想要加载某张图片时,先去LruCache中寻找图片,若是LruCache中有,则直接取出来使用,若是LruCache中没有,则去SoftReference中寻找(软引用适合当cache,当内存吃紧的时候才会被回收。而weakReference在每次system.gc()就会被回收)(当LruCache存储紧张时,会把最近最少使用的数据放到SoftReference中),若是SoftReference中有,则从SoftReference中取出图片使用,同时将图片从新放回到LruCache中,若是SoftReference中也没有图片,则去硬盘缓存中中寻找,若是有则取出来使用,同时将图片添加到LruCache中,若是没有,则链接网络从网上下载图片。图片下载完成后,将图片保存到硬盘缓存中,而后放到LruCache中。编程
Glide缓存机制大体分为三层:内存缓存、弱引用缓存、磁盘缓存。json
三层存储的机制在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中。缓存
使用一个弱引用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中的资源没有外界引用的缘由。网络
图片占用内存的计算公式:图片高度 * 图片宽度 * 一个像素占用的内存大小。因此,计算图片占用内存大小的时候,要考虑图片所在的目录跟设备密度,这两个因素其实影响的是图片的宽高,android会对图片进行拉升跟压缩。
上面笔者只是简单地讲解一下下Glide的内部实现机制,可是这是远远不够的,若是想要对Glide或其它热门三方库有足够具象地了解,就必须深刻源码去感觉其中的艺术。
所以,为了将热门三方库涉及的知识成体系地融合起来,笔者建立了Awesome-Third-Library-Source-Analysis这个项目,为的就是让每个Android工程师可以从如下七个方面全方位地提高本身的技术实力。
项目地址:Awesome-Third-Library-Source-Analysis
深刻理解热门三方库实现原理,从七个角度全方位提高你的功力~
Android最优秀的网络底层框架,没有之一。
Android最优秀的网络封装框架,内含九种经常使用设计模式的灵活运用。
Android使用最普遍的图片加载框架。
Android中数据库操做综合效率最高的框架。
来一块儿探究RxJava的异步、简洁、优雅和它强大的操做符吧!
LeakCanary到底是如何检测出内存泄露的呢?
使用APT + 注解攻破了findViewByid(),JW大神之做。
Dagger就一把匕首,在中大型项目中,它能提高开发效率、自动管理类的实例、解耦,是如此的干脆。
使用扩展的观察者模式实现的组件间通讯框架,广播的替代者。
做者:jsonchao
连接:https://juejin.im/post/5e65ad276fb9a07cc01a3264来源:掘金