`

原来面试的时候写精通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)
分享到:
评论

相关推荐

    90分钟搞定图片加载框架Glide,面试实战一条龙.wmv

    90分钟搞定图片加载框架Glide,面试实战一条龙 1.Glide架构思想解析 2.手写实现Glide基本框架 3.为框架搭载高并发引擎 4.如何处理Glide的缓存机制

    glide_jar包合集

    Glide是一款广泛应用于Android开发中的图像加载库,它以其高效、流畅的图片加载体验而备受开发者喜爱。这个“glide_jar包合集”显然包含了多个版本的Glide库,适用于不同的项目需求或者是为了兼容不同版本的Android...

    glide4.4.0

    glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0glide4.4.0

    glide加载和下载svg矢量图片

    在Android开发中,Glide是一个非常流行的图片加载库,它以其高效、易用和强大的功能深受开发者喜爱。SVG(Scalable Vector Graphics)是一种矢量图格式,与传统的位图图像不同,SVG图像可以无损缩放,不会因为放大而...

    glide-3.7.0.jar

    Glide是Android应用开发中的一个强大且高效的图片加载库,由Bump Technologies打造。这个库的设计目标是简化图片的加载、缓存和显示过程,从而提高应用的性能和用户体验。"glide-3.7.0.jar"是Glide的一个特定版本,...

    golang 下载插件 glide

    这样,即使在没有网络的情况下,你也可以构建项目,因为它包含了所有必要的依赖。 ## 7. 版本锁定 `glide.lock`文件是`glide update`命令生成的,它包含了所有依赖的确切版本。这个文件很重要,因为它确保了在不同...

    glide加载https

    在Android开发中,Glide是一个非常流行的图片加载库,它提供了高效的图片缓存和加载机制,使得在处理图片时能够保持应用的流畅性。当我们需要加载来自HTTPS源的图片时,Glide同样提供了支持。本篇文章将深入探讨如何...

    手写图片加载Glide框架2

    在Android应用开发中,图片加载库是不可或缺的一部分,Glide作为一个高效的图片加载和管理库,被广泛用于处理图片的加载、缓存以及显示。本文将深入探讨如何在自定义需求下,结合Glide框架实现手写图片加载功能,即...

    Glide加载图片库的简单使用

    Glide是Android平台上的一个高效的图片加载库,它旨在简化图片的加载、缓存和显示过程,以提高应用性能和用户体验。Glide以其简洁的API和出色的表现力,在Android开发者中广受欢迎。以下是对Glide在图片加载方面的...

    android:glide各种jar包

    在Android开发中,Glide是一个非常流行的图片加载库,它以高效、简洁的API和出色的性能而备受赞誉。本文将详细解析Glide的各种版本及其jar包,帮助开发者更好地理解和运用这个强大的工具。 Glide的各个版本标志着其...

    手写图片加载Glide框架

    在Android应用开发中,图片加载库是不可或缺的一部分,Glide就是其中非常流行的一个。Glide以其高效的内存管理、流畅的滚动体验以及强大的图片处理能力深受开发者喜爱。本教程将深入探讨如何在Android项目中实现手写...

    glide-4.9.0.jar

    Glide4.9.0.jar是glide图片加载框架最新版本的jar文件,支持eclipse和Android studio。

    Glide的基本用法

    Glide是Android平台上的一个强大的图片加载库,它专注于流畅的用户体验和高效的内存管理,尤其在处理图片加载、缓存和动画方面表现出色。本文将详细介绍Glide的基本用法,帮助开发者更好地理解和应用这一工具。 ###...

    Glide 4.7.0 jar

    Glide4.7.0jar 最新jar包 Glide最流行的一款图片框架,使用方便快捷 大家免费下载吧 有其他问题也可以问我

    Glide 4加载GIF 优化方案

    在Android应用开发中,Glide是一个非常流行的图片加载库,它以其高效、简洁的API而受到开发者们的喜爱。然而,当涉及到加载GIF动图时,可能会遇到性能问题,因为GIF格式本身处理起来就相对复杂。Glide 4加载GIF的...

    Glide4使用简介

    我想大多数人在自己的项目中还是使用Glide3.7.1这个版本吧!不过Glide版本现在已经到4.4.0了! 当我们把Glide3更换成Glide4,会发现大部分地方都报错了,那么该怎样快速替换Glide3为Glide4呢?

    glide-4.0源码

    Glide是Android平台上的一个强大的图片加载库,它在处理图片加载、缓存、缩放等方面表现出色,尤其在优化用户体验方面有独到之处。针对Glide 4.0的源码,我们可以深入理解其工作原理,从而更好地利用它来优化我们的...

    android替换Glide通讯组件为Okhttp并监控加载进度

    这样,Glide就会使用我们配置的Okhttp进行网络请求。 2. **实现加载进度监控:** - 创建一个`Interceptor`来捕获下载进度。`ProgressInterceptor`会在每个响应体的读取过程中更新进度。 ```java public class ...

    Android-使用Glide在Android中加载SVG

    Glide是一个流行的Android图片加载库,它以其高效、易用和强大的功能而闻名。本篇将详细讲解如何在Android应用中使用Glide加载SVG图像。 首先,我们需要了解SVG的基本概念。SVG是一种基于XML的图形语言,它可以描绘...

Global site tag (gtag.js) - Google Analytics