写点什么

原来面试的时候写精通 Glide,这样问我这样答,android 编程权威指南

用户头像
Android架构
关注
发布于: 23 小时前

// 判断 Glide 当前是不是处于暂停状态


onSizeReady()--> `Engine.load(signature, width, height, dataFetcher, loadProvider,transformation, transcoder,priority, isMemoryCacheable, diskCacheStrategy, this)


a)先构建 EngineKey;


b) loadFromCache从 缓 存 中 获 取EngineResource , 如 果 缓 存 中 获 取 到 cache 就 调 用cb.onResourceReady(cached);


c)如果缓存中不存在调用 loadFromActiveResources从 active中获取,如果获取到就调用cb.onResourceReady(cached);


d)如果 active 中也不存在,调用EngineJob.start(EngineRunnable), 从而调用decodeFromSource()/decodeFromCache()-->如果是调 用 decodeFromSource()-->ImageVideoFetcher.loadData()-->HttpUrlFetcher() 调 用HttpUrlConnection进 行 网 络 请 求 资 源 --> 得 于InputStream() 后 , 调 用decodeFromSourceData()-->loadProvider.getSourceDecoder().decode() 方 法 解 码-->GifBitmapWrapperResourceDecoder.decode()-->decodeStream()先从流中读取 2 个字节判断是 GIF 还是普通图,若是 GIF 调用 decodeGifWrapper()来解码,若是普通静图则调用decodeBitmapWrapper()来解码-->bitmapDecoder.decode()`

三丶 Glide 使用什么缓存?

1) 内存缓存: LruResourceCache(memory)+弱引用 activeResourcesMap<Key, WeakReference<EngineResource<?>>> activeResources


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


正在使用的资源,当 acquired 变量大于 0,说明图片正在使用,放到 activeResources 弱引用缓存中,经过 release()后,acquired=0,说明图片不再使用,会把它放进 LruResourceCache


2)磁盘缓存: DiskLruCache,这里分为 Source(原始图片)和 Result(转换后的图片)


第一次获取图片,肯定网络取,然后存 active\disk 中,再把图片显示出来,第二次读取相同的图片,并加载到相同大小的 imageview 中,会先从 memory 中取,没有再去 active 中获取。如果 activity 执行到 onStop 时,图片被回收,active 中的资源会被保存到 memory 中,active 中的资源被回收。当再次加载图片时,会从 memory 中取,再放入 active 中,并将 memory 中对应的资源回收。


之所以需要 activeResources,它是一个随时可能被回收的资源,memory 的强引用频繁读写可能造成内存激增频繁 GC,而造成内存抖动。资源在使用过程中保存在 activeResources 中,而 activeResources 是弱引用,随时被系统回收,不会造成内存过多使用和泄漏。

四丶 Glide 内存缓存如何控制大小?

Glide 内存缓存最大空间(maxSize)=每个进程可用最大内存 0.4(低配手机是 每个进程可用最大内存 0.33)


磁盘缓存大小是 250MB int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;

五丶 LruCache 底层实现原理:

LruCacheLru 算法的实现就是通过 LinkedHashMap 来实现的。LinkedHashMap继承于HashMap,它使用了一个双向链表来存储 Map 中的 Entry 顺序关系,对于 get、put、remove 等操作,LinkedHashMap 除了要做 HashMap 做的事情,还做些调整 Entry 顺序链表的工作。


LruCache 中将 LinkedHashMap 的顺序设置为 LRU 顺序来实现 LRU 缓存,每次调用 get(也就是从内存缓存中取图片),则将该对象移到链表的尾端。调用 put 插入新的对象也是存储在链表尾端,这样当内存缓存达到设定的最大值时,将链表头部的对象(近期最少用到的)移除。

六丶三级缓存原理

当 Android 端需要获得数据时比如获取网络中的图片,首先从内存中查找(按键查找),内存中没有的再从磁盘文件或 sqlite 中去查找,若磁盘中也没有才通过网络获取

七丶如何设计一个大图加载框架

图片加载包含封装,解析,下载,解码,变换,缓存,显示等操作


  • 封装参数: 从指定来源,到输出结果,中间可能经历很多流程,所以第一件事就是封装参数,这些参数会贯穿整个过程;

  • 解析路径: 图片的来源有多种,格式也不尽相同,需要规范化;

  • 读取缓存: 为了减少计算,通常都会做缓存;同样的请求,从缓存中取图片(Bitmap)即可;

  • 查找文件/下载文件: 如果是本地的文件,直接解码即可;如果是网络图片,需要先下载;

  • 解码: 这一步是整个过程中最复杂的步骤之一,有不少细节,下个博客会说;

  • 变换: 解码出 Bitmap 之后,可能还需要做一些变换处理(圆角,滤镜等);

  • 缓存: 得到最终 bitmap 之后,可以缓存起来,以便下次请求时直接取结果;

  • 显示: 显示结果,可能需要做些动画(淡入动画,crossFade 等)

  • 请查看完整的 PDF 版(更多完整项目下载。未完待续。源码。图文知识后续上传 github。)**可以点击[关于我](


)联系我获取完整 PDF**(VX:mm14525201314)



用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
原来面试的时候写精通Glide,这样问我这样答,android编程权威指南