Glide使用及原理分析

2023-10-27


前言

Glide是一款非常好用的图片加载框架那么它具体好用在哪里呢?

总所周知,在android开发中有几大令人头疼的问题,比如内存泄漏,线程问题,生命周期,这些问题在Glide的身上都不需要关心,下面就具体来介绍一下Glide的使用及原理吧。


一、Glide的基本使用

Glide.with(MainActivity.this)
                        .load(url)
                        .asGif()  // 加载gif图片
                        .placeholder(res)  // 加载成功前显示图片
                        .diskCacheStrategy(DiskCacheStrategy.NONE)  // 不使用Glide缓存
                        .error(res2) // 加载图片失败显示的图片
                        .into(imageView); // 显示图片

二、Glide的网络请求

1.HttpURLConnection实现一个原生图片加载框架

  • 子线程请求网络
  • 渲染UI
  • 切换到主线程
  • 将流转成Bitmap
  • Bitmap设置到imageView

Glide的网络请求也是HttpURLConnection

2.Glide为什么能监听网络变化

监听网络变化,重新进行一次网络请求restartRequests(),其中request.begin()

LRU算法:LinkedHashMap,双向链表,查询快,最近访问的元素在栈顶

切换线程Handler:EngineRunnable中切岛子线程,走三级缓存,若没有走网络请求,into之前切回主线程


三、Glide的生命周期

1.Fragment的生命周期,动态加载Fragment

Fragment生命周期

  • onAttach():关联之后调用

  • onCreate():Fragment初次创建时调用(不能去拿activity的UI控件)

  • onCreateView():设置fragment的view

  • onActivityCreated(): 可以拿activity的UI控件

activity先onCreate(),后onDestroy()

无UI的Fragment,没有视图,只是进行声明周期的监听

into时会判断是否为主线程

onDestroy()会清除内存,硬盘文件没有被清除

2.Glide如何管理管理生命周期

RequestManagerRetriever创建一个无UI的Fragment,传到Activity上,并将这个Fragment的生命周期绑定到RequestManager上

  • 如果当前页面停止,onStop()方法被调用,所有运行中的请求都会停止,加入到等待队列中,开始运行后,放回运行队列中

  • 当Activity调用onStop()时,隐式调用Fragment的onStop()方法,通过调用RequestManager,来管理两个队列的请求

3.Glide为什么要缓存Fragment

SupportRequestManagerFragment中缓存

1、防止每次都创建一个Fragment(复用)

2、当前Fragment放进去会把上一个Fragment移除(不会造成内存泄露)

3、多个activity时,防止多个Fragment导致管理生命周期紊乱,保证只有一个Fragment,保证Glide的生命周期和当前显示的Activity保持一致


四、Glide如何监测内存

在这里插入图片描述
Activity和Fragment中都有一个ComponentCallback接口,里面onTrimMemory方法(回调接口)

而Glide在RequestManagerFragment中监听onTrimMemory,onLowMemory中glide.clearMemory(),clearMemory中对内存缓存和BitmapPool进行清除

key不变,value变了,还是请求原来的图片(有缓存)


五、Glide的三大主线

Glide.with(this).load(url).into(iv_image1);

主线

1.Glide的with主线

  • new一个Glide对象:build构建者模式

  • 创建了一个空Fragment:绑定生命周期实现了Lifecycle接口

  • 把生命周期方法传导出去

2.Glide的load主线

构建RequestBuilder对象,把Url传进去

3.Glide的into主线

  • engine.load中三级缓存(EngineKey)

    • 活动缓存(Hashmap)(弱引用缓存)

    • 内存缓存(Lru算法)

    • 磁盘缓存(Lru算法)

  • 从主线程切换到子线程去请求网络数据

  • 切回主线程

  • 主线程渲染数据

  • 图片裁剪,自适应


六、Glide三大缓存

通过key值去取,存的时候把key存进去

  • 活动缓存:针对当前activity有效,activity被干掉就没了

  • 内存缓存:针对当前app有效(Lru,有数量限制)

  • 磁盘缓存:app没被卸载就有效

1、手写活动缓存(activityCache):get,set,remove

  • Lru无法识别特殊字符串,通过算法将url转成一个key

  • 不能一边遍历,一边删除,数组长度变化,会下标越界

  • 删除:通过迭代器去删除

2、手写内存缓存(memoryCache):继承Lruche,设定一个最大值

3、手写磁盘缓存(DiskLruCache):io交互,内存问题,算法

  • 单例模式,文件路径,DiskLruCache,get,put

4、Engine引擎:读取缓存,读取逻辑,事件分发给EngineJob

  • 从服务器读取图片之后存到磁盘缓存,当前activity可见存到活动缓存(弱引用持有数据,不会造成OOM),不可见存到内存缓存

  • 读取逻辑:

    • 先找活动缓存,活动缓存中有,存入内存缓存,活动缓存中删除

    • 没有,找内存缓存,内存缓存中有,存入活动缓存,内存缓存中删除(相互互补互删)

    • 没有,去找磁盘缓存

  • EngineJob:继承自Runnable,做网络请求

5、活动缓存和内存缓存区别

  • 作用域不同

  • 内存缓存有maxSize

6、Glide缓存会缓存两份,不是三份

7、Glide存是若没有设置大小,会存一个和手机分辨率匹配的图片


总结

Glide整体流程:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Glide使用及原理分析 的相关文章

随机推荐

  • 图书管理系统【C++】

    图书借阅管理系统 C 文章目录 图书借阅管理系统 C 一 需求分析 二 程序主要功能 三 程序运行平台 四 程序框架 五 文件说明 六 程序代码 七 使用展示 1 开始运行 2 读者系统 3 图书系统 4 借书还书 八 后记 一 需求分析
  • Wwise指引贴

    几种音频软件的比较 Criware音频引擎跟Wwise在功能上有什么直接的区别么 为什么很多大厂都选择Wwise
  • 关系型数据库ACID与非关系型数据的CAP

    ACID 事务的原子性 Atomicity 是指一个事务要么全部执行 要么不执行 也就是说一个事务不可能只执行了一半就停止了 比如你从取款机取钱 这个事务可以分成两个步骤 1划卡 2出钱 不可能划了卡 而钱却没出来 这两步必须同时完成 要么
  • 剑指Offer - 面试题23:链表中环的入口节点

    题目 如果一个链表中包含环 如何找出环的入口节点 例如 在下图中的链表中 环的入口节点是节点3 分析 将这个问题解剖开 分为俩步 判断是否有环 有环再找入口节点 第一个问题 我们用快慢指针来判断 只要相遇就有环 快指针走到头就是没有环 第二
  • JS中Date()和New Date()的区别

    最近用日期控件用的比较多 所以说一说Date 和New Date 之间的区别 var c 1 Date 返回一个字符串 string 没有getDate等日期对象方法 内容为当前时间 var c2 new Date 返回一日期对象 可以调用
  • 生成性对抗网络(GAN) 和styleGan

    生成性对抗网络 GAN 是机器学习中一个相对较新的概念 于2014年首次引入 他们的目标是合成与真实图像无法区分的人工样本 如图像 GAN应用程序的一个常见示例是通过从名人面孔数据集学习来生成人造人脸图像 随着时间的推移 GAN图像变得更加
  • C#面试题

    1 维护数据库的完整性 一致性 你喜欢用触发器还是自写业务逻辑 为什么 答 尽可能用约束 包括CHECK 主键 唯一键 外键 非空字段 实现 这种方式的效率最好 其次用触发器 这种方式可以保证无论何种业务系统访问数据库都能维持数据库的完整性
  • telnet传输文件:telnet登录Linux后通过busybox ftpget获取远程文件

    telnet传输文件 telnet登录Linux后通过busybox ftpget获取远程文件 文章目录 telnet传输文件 telnet登录Linux后通过busybox ftpget获取远程文件 1 场景 2 telnet登录 3 b
  • 【TIP】已经上架的app在AppStore上搜不到的解决办法

    appstore上架后搜不到APP 修改定价 将你的app定价修改成0 99刀 修改你的发行范围 全取消后只选中国 save 这时候你的app status将会变成pending contract 将之前的修改都改回来 修改定价free 全
  • Mac系统下Android studio配置环境变量(ADB、JDK、GRADLE、Flutter)

    mac os 启动台 gt 终端 进入当前用户的home目录 默认 cd 若 bash profile文件不存在则创建 touch bashrc 名字可以自己定义 bash profile 打开 bash profile 文件不存在则创建则
  • 第六章 系统总线

    http eduunix ccut edu cn index2 edu C7 E5 BB AA B4 F3 D1 A7 BC C6 CB E3 BB FA BF CE B3 CC CE A2 D0 CD BC C6 CB E3 BB FA
  • 阿里P8精心整理的微服务系统架构设计手册,一睹微服务架构世界

    近几年 微服务架构在大量技术社区迅速蹿红 被认为是 IT 软件架构的未来方向 一线互联网公司由于具有大量的业务体量和业务场景 比如阿里 百度 网易 很早就开始入坑微服务架构 随着云端办公以来 发现微服务越来越重要了 Docker 容器技术和
  • MatConvNet:3.代码(一)cnn_mnist.m注释

    原文链接 https blog csdn net qq 20259459 article details 54411178 博主博客地址 http blog csdn net qq 20259459 作者邮箱 jinweizhi93 gma
  • 用函数完成两个数相加(用两个方法实现)

    用函数完成两个数相加 1 方法一 int f1 int x int y 声明函数 定义函数 int z z x y return z include
  • JAVA 敏感词过滤

    package me mymilkbottles import org apache commons lang CharUtils import java io File import java util HashMap import ja
  • 基于vue+leaflet+echart的足迹分享评论平台

    其实题目是随便取的 目的只是用来证明Vue leaflet springboot技术栈的可行性 效果 小专栏不支持上传视频 想看的话可以去我的知乎看最新的文章 那个应该可以 在这里 主要功能描述 vue leaflet结合 足迹管理 新建
  • python编程-2.编写程序,输出所有由1,2,3,4这四个数字组成的素数,并且每个数字在素数中只出现一次。

    data用于存储在一定范围内的素数 data set for n in range 1234 4321 1 if n 2 0 continue for i in range 3 int n 0 5 1 2 if n i 0 break el
  • 组合逻辑电路——编码器

    组合逻辑电路 编码器 概念 编码的概念 在数字系统中 常需要将有特定意义的信息编成二进制代码 这一过程称为编码 编码器 实现编码的数字电路被称为编码器 二进制编码器 这里我们采用与非门来设计二进制编码器 二进制编码器输出端数量不定 可以根据
  • ACM MM 2022

    有预训练 460多m 来源丨https zhuanlan zhihu com p 547671620 Bidirectional Self Training with Multiple Anisotropic Prototypes for
  • Glide使用及原理分析

    文章目录 前言 一 Glide的基本使用 二 Glide的网络请求 1 HttpURLConnection实现一个原生图片加载框架 2 Glide为什么能监听网络变化 三 Glide的生命周期 1 Fragment的生命周期 动态加载Fra