`

原来面试的时候写精通Glide,这样问我这样答

阅读更多

前言

这几天在很多地方看到有聊Glide的,想起前年还是去年的时候面试的时候也有问到Glide相关的,正好今天趁着周五来聊一聊面试中Glide的那些东西

  • 1 、图片库对比
  • 2 、LRUCache 原理
  • 3丶LruCache 底层实现原理
  • 4 、图片加载原理
  • 5 、自己去实现图片库,怎么做?
  • 6 、Glide 源码解析
  • 7 、Glide 使用什么缓存
  • 8 、Glide 内存缓存如何控制大小?
  • 9丶三级缓存原理?
  • 10丶如何设计一个大图加载框架?

面试整理学习路线(禁止偷偷拿走O(∩_∩)O)

 

Android核心技术面试必备.png
Android核心技术面试必备.png


请查看完整的PDF版
(更多完整项目下载。未完待续。源码。图文知识后续上传github。)
可以点击关于我联系我获取完整PDF
(VX:mm14525201314)

 

一丶LRUCache 原理

LruCache 是个泛型类,主要原理是:把最近使用的对象用强引用存储在 LinkedHashMap 中,当缓存满时,把最近最少使用的对象从内存中移除,并提供 get/put 方法完成缓存的获取和添加LruCache 是线程安全的,因为使用了 synchronized 关键字。

当调用 put()方法,将元素加到链表头,如果链表中没有该元素,大小不变,如果没有,需调用 trimToSize 方法判断是否超过最大缓存量,trimToSize()方法中有一个 while(true)死循环,如果缓存大小大于最大的缓存值,会不断删除 LinkedHashMap 中队尾的元素,即最少访问的,直到缓存大小小于最大缓存值。当调用 LruCache 的 get 方法时,LinkedHashMap 会调用recordAccess 方法将此元素加到链表头部

二、Glide 源码解析

1)Glide.with(context)创建了一个 RequestManager,同时实现加载图片与组件生命周期绑定:
在 Activity 上创建一个透明的 ReuqestManagerFragment 加入到 FragmentManager中,通过添加的 Fragment 感知Activty\Fragment 的生命周期。因为添加到 Activity 中的 Fragment 会跟随Activity 的生命周期。在 RequestManagerFragment中的相应生命周期方法中通过 liftcycle 传递给在 lifecycle 中注册的 LifecycleListener

2)RequestManager.load(url) 创建了一个 RequestBuilder<T>对象 T 可以是 Drawable 对象或是 ResourceType 等

3 ) RequestBuilder.into(view)-->into(glideContext.buildImageViewTarget(view, transcodeClass))返 回 的 是 一 个DrawableImageViewTarget, Target 用 来 最 终 展 示 图 片 的 ,buildImageViewTarget-->ImageViewTargetFactory.buildTarget()根据传入 class 参数不同构建不同的 Target 对象,这个 Class 是根据构建 Glide 时是否调用了 asBitmap()方法,如果调用了会构建出BitmapImageViewTarget,否则构建的是GlideDrawableImageViewTarget 对象。
-->GenericRequestBuilder.into(Target), 该 方 法 进 行 了 构 建 Request , 并 用RequestTracker.runRequest()-->GenericRequest.begin()

 Request request = buildRequest(target);
         // 构建 Request 对象, 
        target.setRequest(request);
        lifecycle.addListener(target);
 requestTracker.runRequest(request);
       // 判断 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)+弱引用 activeResources
Map<Key, WeakReference<EngineResource<?>>> activeResources正在使用的资源,当 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 底层实现原理:

LruCache 中 Lru 算法的实现就是通过 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)
分享到:
评论

相关推荐

    值得借鉴的6个优秀的Android简历

    在Android开发领域,一份出色的简历是成功面试的关键。以下是对标题和描述中提及知识点的详细说明,以及如何根据这些知识点来构建一个引人注目的Android开发者简历。 1. **自我介绍**: 自我介绍部分应该简洁明了...

    Android开发者资料大全(开发人员必看)

    【Android开发者资料大全】是为Android开发者精心整理的一份资源集合,涵盖了从入门到精通的全方位知识体系。这份资料包旨在帮助开发者系统性地学习和提升Android开发技能,以下是其中包含的一些关键知识点: 1. **...

    bytetrack的跟踪效果

    dancetrack0004的gt

    2023年全球房地产行业并购趋势:政策调整与市场需求变化下的投资机遇

    本文由普华永道发布,详细分析了2023年全球房地产行业的并购趋势。在全球宏观经济环境变化和货币政策调整背景下,房地产并购活动有所放缓,但仍有大量资金等待入场。文中探讨了办公、工业、住宅、零售和酒店五大板块的具体情况及其面临的挑战与机遇。办公资产受利率上调影响较大,但优质资产需求仍然旺盛;工业地产在电商和供应链调整驱动下持续增长;住宅市场因利率上升导致租赁需求增加;零售业则受益于消费者回归实体店;酒店业则因旅游需求回暖而保持高位并购活动。此外,文章还提到不同区域市场的特点,如美洲、欧洲、中东和亚太地区的具体动态。

    计算机二级题库(已经分类).pdf

    计算机二级题库(已经分类).pdf

    intel pcm官方资源

    intel pcm

    汽车入门必读,深刻了解底层逻辑

    汽车入门必读,深刻了解底层逻辑

    计算机二级模拟试题.pdf

    计算机二级模拟试题.pdf

    计算机发展和特点.pdf

    计算机发展和特点.pdf

    基于java的图书馆管理系统毕业设计含源文件.doc

    基于java的图书馆管理系统毕业设计含源文件.doc

    计算机汇编原理.pdf

    计算机汇编原理.pdf

    基于Linux平台的机器人控制系统与路径识别设计方案

    内容概要:本文详细介绍了基于Linux平台的机器人控制系统和路径识别项目的完整设计方案。

    计算机二级计算机编程题.pdf

    计算机二级计算机编程题.pdf

    基于网络流量的设备识别技术综述与发展前景

    内容概要:本文详细介绍了基于网络流量的设备识别技术,涵盖了其发展历史、TCP/IP协议的基础知识以及当前的研究进展。文章首先回顾了早期设备识别的需求和方法,指出随着物联网设备的多样化和复杂化,传统的设备识别方法已难以满足现代需求。接着探讨了高性能扫描工具的作用,强调了TCP/IP各层协议在网络流量分析中的重要性。文中还深入讨论了两种主要的设备识别方法:基于协议特征和统计特征的分类器学习,以及基于应用层数据的自动化规则生成。最后,文章指出了现有方法的优点和局限性,并展望了未来的研究方向。 适合人群:信息安全研究人员、网络管理员、物联网开发者和技术爱好者。 使用场景及目标:适用于希望深入了解设备识别技术原理及其应用场景的专业人士,旨在帮助他们掌握最新的技术和工具,以应对日益复杂的网络安全挑战。 其他说明:文章引用了两篇权威文献,提供了详尽的技术细节和案例分析,有助于读者全面理解设备识别领域的最新进展。

    汇编语言 + x86 架构 + 密码本程序开发 + 助力汇编学习

    1. **内容概要**:x86版本汇编密码本程序基于x86汇编编写,支持增删改查。程序经x86架构优化,执行效率高、兼容性好。 2. **适用人群**:适合学习x86汇编的学生、加密技术爱好者、信息安全开发者以及逆向工程从业者。 3. **使用场景及目标**:在数据传输和存储场景下,对敏感数据加密,保障数据安全。学习者能借此深入理解汇编与加密算法,开发者可将其功能集成到项目中。 4. **其他说明**:程序基于x86架构,在其他架构使用可能需适配。使用者需具备一定汇编和加密知识,使用时应遵守法律法规,关注技术动态,适时更新程序 。

    BAT经典面试题解析:涵盖C++、数据结构与算法、操作系统等领域的深度探讨

    内容概要:本文档汇集了 BAT(百度、阿里巴巴、腾讯)的经典面试题目及其详细解答,涵盖了广泛的技术领域。主要内容包括 STL 容器(如 vector、Map、Set)的实现原理,洗牌算法的设计,竞赛排序问题,中位数查找算法,智能指针的实现与循环引用处理,单例模式的线程安全实现,C++ 结构体大小计算,引用与指针的区别,const 和 define 的对比,强制类型转换的区别,虚函数的工作原理,内存管理和多线程编程技巧,Linux 内存分配机制,以及各种算法设计问题(如短网址服务、网页爬虫、大数据处理等)。这些问题不仅涉及基础知识的理解,还包括实际应用场景中的优化和解决方案。 适合人群:具备一定编程基础和技术背景的研发人员,尤其是准备 BAT 技术面试的候选人。 使用场景及目标:①深入理解 C++ 编程语言特性及其标准模板库的实现细节;②掌握常见的数据结构和算法设计技巧;③熟悉操作系统层面的知识,如内存管理、进程通信等;④提高解决实际工程问题的能力,特别是在大规模数据处理方面。 其他说明:文档中的题目难度较大,旨在考察应聘者的综合能力,包括但不限于理论知识的应用、代码实现的质量、解决问题

    基于Carsim与Simulink的ACC自适应巡航控制系统联合仿真及优化

    内容概要:本文详细介绍了如何利用Carsim进行车辆动力学建模并结合Simulink实现ACC(自适应巡航控制)系统的联合仿真。文中涵盖了从环境配置、模型搭建、控制算法设计到最后的数据同步等多个方面。尤其强调了在配置过程中容易出现的问题及其解决方案,如单位制转换、采样时间同步以及PID控制器参数调优等。此外,作者分享了一些实用的经验技巧,如通过状态机实现跟车模式切换、采用抗饱和PID结构提高控制稳定性等。 适用人群:从事汽车电子控制系统开发的技术人员,尤其是对ACC系统感兴趣的工程师。 使用场景及目标:帮助开发者掌握Carsim与Simulink联合仿真的全流程,确保能够成功搭建并优化ACC控制系统,最终达到稳定可靠的跟车效果。 其他说明:文中提供了大量MATLAB/Simulink代码片段作为实例指导,有助于读者更好地理解和应用相关知识点。同时,针对可能出现的各种问题给出了详细的排查步骤和技术建议。

    计算机二级VB考试_试题(真题)及详细答案.pdf

    计算机二级VB考试_试题(真题)及详细答案.pdf

    计算机仿真作业3.pdf

    计算机仿真作业3.pdf

    华为NAC技术白皮书:网络接入控制解决方案及其应用场景

    内容概要:本文档详细介绍了华为的NAC(网络接入控制)技术,涵盖802.1X认证、MAC认证和Portal认证等多种认证方式。NAC作为一种‘端到端’的安全架构,旨在保障网络安全接入,防止非法终端接入和合法终端越权访问。文档还探讨了各种认证方式的具体实现细节,包括认证流程、配置命令和故障处理方法。此外,文档提供了具体的组网应用实例,帮助用户理解和部署NAC解决方案。 适合人群:网络管理员、信息安全专家、IT运维人员和技术支持团队。 使用场景及目标:适用于企业内部网络的安全管理和控制,特别是需要对用户终端进行严格认证和授权的场景。通过NAC技术,可以提高网络安全性,防止未经授权的访问,保护核心资源。 其他说明:本文档不仅涵盖了理论和技术背景,还包括了详细的配置指南和故障排除步骤,有助于用户全面掌握NAC技术的实际应用。

Global site tag (gtag.js) - Google Analytics