Android 图片加载框架Glide源码详解

news2024/10/7 10:19:42

我们看Glide的源码从Glide类入手,使用的时候我们先调用的with方法,源码中with有3个多载的方法:下图翻译过来就是activity用FragmentActivity Applicationcontext用 with(Context)还有一个with(View)的
在这里插入图片描述
殊途同归,最后都是调用了getRetriever(context).get(context),我们看看最后的get(context)方法 ,如下图, 这就大致分成两类一种是ApplicationContext, 一种是activity,fragment ,两种lifecycle生命周期,下图是证明:
在这里插入图片描述
在这里插入图片描述
为什么要区分Applicationlifecycler和Activitylifecycler 呢?
在Glide中,区分Application Lifecycle和Activity Lifecycle主要是为了更好地管理图像加载和缓存的策略。

Application Lifecycle:在Android应用程序中,Application Lifecycle指的是从应用程序启动到关闭的整个生命周期。在这个生命周期中,Glide可以根据应用程序的整体状态来调整其行为。例如,当应用程序处于后台时,Glide可以减少图像加载的频率或暂停加载,以节省资源和电量。而在应用程序重新进入前台时,Glide可以恢复正常的加载行为。
Activity Lifecycle:Activity Lifecycle指的是一个Activity从启动到销毁的周期。在这个生命周期中,Glide可以与Activity的各个生命周期回调方法进行交互,以便在适当的时机加载和显示图像。例如,当Activity在用户面前时(onResume()调用后),Glide可以在该时机加载并显示图像。而在Activity被用户离开时(onPause()调用后),Glide可以暂停加载或释放一些资源。
通过区分这两个生命周期,Glide可以更精细地控制图像加载和缓存的行为,以适应不同场景和应用程序需求。这有助于提高应用程序的性能、节省资源并提高用户体验。

同时glide的初始化也是在这里getRetriever方法中完成的
在这里插入图片描述
在这里插入图片描述

从图上我们也可以看出来with 方法返回的是RequestManager, 里面有一个TargetTracker 跟踪view target的 ,每当RequestManage生命周期变化时,通知各个view。
在这里插入图片描述
在这里插入图片描述
现在是不是能想到,之前聊的lifecycler两种生命周期和它对上了,Application和activity等他们的生命周期会调用manager的,manager再通知各个view,贯通了整个框架。给你们看一下添加的listener
在这里插入图片描述

RequestManager集合了glide的要用的各种类,对Request进行管理,其中里面的load方法返回的是RequestBuilder,这里的load实际上还是调用RequestBuilder里面的load
在这里插入图片描述
load的方法还是挺空的,重点是赋值这个model 图片地址。
在这里插入图片描述

从下图可以看出,RequestBuilder这个类才是Builder设计模式的主类,我们使用中最后的into方法返回的是Target,大部分逻辑都在这个方法里面了, buildRequest就是重点,

在这里插入图片描述

在这里插入图片描述
然后走的是obtainRequest
在这里插入图片描述
SingleRequest.obtain
在这里插入图片描述
SingleRequest获得后,在begin方法中
在这里插入图片描述
有个onSizeReady
在这里插入图片描述
主角登场,engine.load方法。
在这里插入图片描述
里面有glide加载缓存的逻辑
在这里插入图片描述
下图可以看到是先加载内存中的处理过的resource,里面是一个hashmap维护的key resource 键值对的缓存,第二个就是采取了lru算法的采用linkedhashmap的内存数据
在这里插入图片描述
然后是调用了waitForExistingOrStartNewJob方法,开始decodeJob 解码工作
在这里插入图片描述
runWrapped()方法, runGenerators方法, currentGenerator.startNext()
在这里插入图片描述
值得看的是currentGenerate是下图中3个的哪一个呢,从逻辑上看3个会依次遍历,分别是先处理过的resource缓存,然后是data缓存,最后是Source网络加载, 这也是glide的三级缓存。我们只讲一个SourceGenerator,里面也有下载图片的modelloader,其他两个的逻辑差不多,不再赘述了。下面就要开始讲根据model,data找modelloader的逻辑了,做好心理准备,不简单,网上大都是一笔带过(因为他们也弄不清,的确有点复杂,绕来绕去),好不容易全网找到一篇,不知道是他的版本旧的,还是他理解的不对,珍惜吧,我认为是全篇最难的地方了。

在这里插入图片描述
3个也都会调用loadData.fetcher.loadData,重点是找到这个loadData
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
handles 过滤筛选出可以处理我们数据类型model的modelloader ,比如我们图片用的是https的String
在这里插入图片描述
String的有3个,但如果你是http开头的网络url的话就只有StringLoader.Streamfactory了,可以看他们3个各种的handles
在这里插入图片描述
还没完,用Uri InputStream 来代替执行
在这里插入图片描述
有5个,而符合我们http或https的就只有append(Uri.class, InputStream.class, new UrlUriLoader.StreamFactory())了
在这里插入图片描述
在这里插入图片描述
又转为GlideUrl.class, InputStream.class,我们再去工厂里面找,经过三次我们才真正找到 HttpGlideUrlLoader.Factory()

在这里插入图片描述
想起前面sourceGenerate 的 loaddata.fetcher.loaddata没有,就是这个HttpUrlFetcher
在这里插入图片描述
下载图片的找到了,拿到数据之后的data的回调就是listener来做了,比较简单就不说了,至此难点讲完了。
在这里插入图片描述
然后我们跳回SingleRequest类中

然后你会发现这个begin是由 RequestManager.into方法中的requestManager.track(target, request);发起的
在这里插入图片描述
在这里插入图片描述

随后我们看一下as相关的方法,有三个,其实是两个GifDrawable和drawable是一类,还有一类是bitmap,那么glide为什么将drawable和bitmap 分开呢
在这里插入图片描述

看下图,因为glide把两种分成了两个类target view,view的setImageBitmap 和setImageDrawable两个不同的方法加载Resource。

在这里插入图片描述

再有就是RequestBuilder关于apply函数加载options
RequestOptions options = new RequestOptions()

            .placeholder(R.mipmap.loading)                //加载成功之前占位图

            .error(R.mipmap.loading)                    //加载错误之后的错误图

            .override(400,400)                                //指定图片的尺寸

            //指定图片的缩放类型为fitCenter (等比例缩放图片,宽或者是高等于ImageView的宽或者是高。)

            .fitCenter()

            //指定图片的缩放类型为centerCrop (等比例缩放图片,直到图片的狂高都大于等于ImageView的宽度,然后截取中间的显示。)

            .centerCrop()

            .circleCrop()//指定图片的缩放类型为centerCrop (圆形)

            .skipMemoryCache(true)                            //跳过内存缓存

            .diskCacheStrategy(DiskCacheStrategy.ALL)        //缓存所有版本的图像

            .diskCacheStrategy(DiskCacheStrategy.NONE)        //跳过磁盘缓存

            .diskCacheStrategy(DiskCacheStrategy.DATA)        //只缓存原来分辨率的图片

            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)    //只缓存最终的图片

             .dontTransform()  //禁用图形变换功能,这个方法时全局的,导致其他地方的图片也不可进行图形变换了,慎用.

            .dontAnimate();//跳过动画

Glide还实现了ComponentCallbacks2接口,这个是内存监测的,我们的Activity等也都会用它
在这里插入图片描述
在内存不足的时候,对自己占用的进行清理。
在这里插入图片描述
最后用图来总结吧,没有捋顺的童鞋可以参考看看,有其他疑问的,咱评论区见了。
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1017627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

西瓜书读书笔记整理(六)—— 第六章 支持向量机

第六章 支持向量机 6.1 间隔与支持向量6.1.1 什么是支持向量机6.1.2 支持向量与间隔6.1.3 支持向量机的求解过程 6.2 对偶问题(dual problem)6.2.1 什么是对偶问题6.2.2 如何求解支持向量机的对偶问题 6.3 核函数(kernel function&#xff09…

基于Xml方式的Bean的配置-Bean的作用范围scope配置

SpringBean的配置详解 Bean的配置范围 默认情况下(基本的Spring环境),单纯Spring环境Bean的作用范围有两个:Singleton和prototypesingleton:单例,默认值,Spring容器创建的时候,就会进行Bean的实…

【VS Code】根据时间和文件名查看增删改的历史记录

我的 VS Code 已设置为自动保存。 左下角这个 TIMELINE 里面记录着我们使用 VS Code 操作各文件的历史记录。 打开 Local History 可以根据时间和文件名查看增删改的历史记录,比如: 然后我们根据时间和文件名,打开一个文件: 即可…

讲座1:影像重建_脑疾病_大脑解码

视频来源:https://www.bilibili.com/video/BV11K4y1979o/?spm_id_from333.999.0.0&vd_source897075bbdd61e45006d749612d05a2ab 文章目录 Image Reconstruction and SegmentationMR Image ReconstructionBrain ROI Segmentation Brain Disease --- Alzheimers…

嵌入式开源组件——LwRB(RingBuffer)的移植和应用

说明:记录自己学习的过程,如有理解上的错误或者不恰当的地方请原谅。 一、简介 LwRB 是一个针对嵌入式系统优化的通用FIFO(先进先出)缓冲区库,之前的名称叫做RingBuffe ,不知道作者在V2.0.0版本时&…

C++11线程库简介

前言 在c11之前涉及多线程的问题都是和平台相关的,比如windows和linux都有一套自己的接口,这使得代码的可移植性变差。C11中最重要的特性就是对线程进行了支持,使得C在编程时不再依赖第三方库,而且原子操作中还引入了原子类的概念…

消息队列(六):服务器设计

紧接着上一章没说完的进行服务器的补充。 推送给消费者消息的基本实现思路 让 brokerServer 把哪些消费者管理好收到对应的消息,把消息推送给消费者 消费者是以队列为维度来订阅消息的,一个队列可以有多个消费者(此处我们约定按照轮询的方…

HTTP协议(超级详细)

HTTP协议介绍 基本介绍: HTTP:超文本传输协议,是从万维网服务器传输超文本到本地浏览器的传送协议HTTP是一种应用层协议,是基于TCP/IP通信协议来传送数据的,其中 HTTP1.0、HTTP1.1、HTTP2.0 均为 TCP 实现&#xff0…

激光焊接汽车PP塑料配件透光率测试仪

随着汽车主机厂对车辆轻量化的需求越来越强烈,汽车零部件轻量化设计、制造也成为汽车零部件生产厂商的重要技术指标。零部件企业要实现产品的轻量化,在材料指定的情况下,要通过产品设计优化、产品壁厚减小和装配方式的优化来解决。使用PP材料…

React 把useState变成响应式 ,今天又可以早点下班了

Ⅰ、前言 我们知道 React 中 , 要想修改 「状态」 > 必须要「state , setState」 useState() 中「setState」 去修改 > 「state」那么如果用 Proxy > 去改造 useState,那么 「摸鱼的时间」又增加啦 ? Ⅱ、proxy 改造 useState 首…

数据结构与算法之Floyd算法-最短路径问题

Floyd算法-最短路径问题 Floyd算法-最短路径问题算法结束算法思想算法效率分析 Floyd算法-最短路径问题 算法结束 Floyd算法:求出每一对顶点之间的最短路径 核心:使用动态规划思想,将问题的求解分为多个阶段: 对于n个顶点的图…

数据结构---绪论

🌞欢迎来到数据结构的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 📆首发时间:🌹2023年9月17日&…

HTTP代理反爬虫技术详解

HTTP代理是一种网络技术,它可以将客户端的请求转发到目标服务器,并将服务器的响应返回给客户端。在网络安全领域中,HTTP代理经常被用来反爬虫,以保护网站的正常运营。 HTTP代理反爬虫的原理是通过限制访问者的IP地址、访问频率、U…

typeScript 类型推论

什么是类型推论? 类型推论是 TypeScript 中的一个特性,它允许开发人员不必显式地指定变量的类型。相反,开发人员可以根据变量的使用情况让 TypeScript 编译器自动推断出类型。例如,如果开发人员将一个字符串赋值给一个变量&#…

【自然语言处理】【大模型】RWKV:基于RNN的LLM

相关博客 【自然语言处理】【大模型】RWKV:基于RNN的LLM 【自然语言处理】【大模型】CodeGen:一个用于多轮程序合成的代码大语言模型 【自然语言处理】【大模型】CodeGeeX:用于代码生成的多语言预训练模型 【自然语言处理】【大模型】LaMDA&a…

MySQL数据库详解 三:索引、事务和存储引擎

文章目录 1. 索引1.1 索引的概念1.2 索引的作用1.3 如何实现索引1.4 索引的缺点1.5 建立索引的原则依据1.6 索引的分类和创建1.6.1 普通索引1.6.2 唯一索引1.6.3 主键索引1.6.4 组合索引1.6.5 全文索引 1.7 查看索引1.8 删除索引 2. 事务2.1 事务的概念2.2 事务的ACID特性2.2.1…

Java 高频疑难问题系列一

​​​​​​​ 目录 ​编辑​​​​​​​ 1.零长度 2.redis的有序集的排序 3.Unsafe类 4.带资源的try语句 5.Spring如何实现计划任务 6.Java中普通代码块,构造代码块,静态代码块执行顺序 7.MyBatis缓存机制 8.Redis Java 2种类型操作转换 9.CAS底层原理和问题 1…

【数据分享】2006-2021年我国城市级别的市容环境卫生相关指标(20多项指标)

《中国城市建设统计年鉴》中细致地统计了我国城市市政公用设施建设与发展情况,在之前的文章中,我们分享过基于2006-2021年《中国城市建设统计年鉴》整理的2006—2021年我国城市级别的市政设施水平相关指标、2006-2021年我国城市级别的各类建设用地面积数…

【pytorch】模型常用函数(conv2d、linear、loss、maxpooling等)

1、二维卷积函数——cnv2d(): in_channels (int): 输入通道数 out_channels (int): 输出通道数 kernel_size (int or tuple): 卷积核大小 stride (int or tuple, optional): 步长 Default: 1 padding (int, tuple or str, optional): 填充 Default: 0 padding_mode (str, optio…

计算机是如何工作的下篇

操作系统(Operating System ) 操作系统是一组做计算机资源管理的软件的统称。目前常见的操作系统有:Windows系列、Unix系列、Linux系列、OSX系列、Android系列、iOS系列、鸿蒙等. 操作系统由两个基本功能: 对下,要管理硬件设备. 对上,要给…