当前位置: 首页 > news >正文

新版Glide检测生命周期原理

本文章使用的是glide 4.15.1

public class RequestManagerRetriever implements Handler.Callback {rivate final LifecycleRequestManagerRetriever lifecycleRequestManagerRetriever;public RequestManagerRetriever(@Nullable RequestManagerFactory factory, GlideExperiments experiments) {//构造函数this.factory = factory != null ? factory : DEFAULT_FACTORY;lifecycleRequestManagerRetriever = new LifecycleRequestManagerRetriever(this.factory);
}@NonNull
public RequestManager get(@NonNull FragmentActivity activity) {if (Util.isOnBackgroundThread()) {return get(activity.getApplicationContext());}assertNotDestroyed(activity);frameWaiter.registerSelf(activity);boolean isActivityVisible = isActivityVisible(activity);Glide glide = Glide.get(activity.getApplicationContext());return lifecycleRequestManagerRetriever.getOrCreate(activity,glide,activity.getLifecycle(),//关键代码activity.getSupportFragmentManager(),isActivityVisible);
}
}final class LifecycleRequestManagerRetriever {@Synthetic final Map<Lifecycle, RequestManager> lifecycleToRequestManager = new HashMap<>();@NonNull private final RequestManagerFactory factory;LifecycleRequestManagerRetriever(@NonNull RequestManagerFactory factory) {this.factory = factory;}RequestManager getOrCreate(Context context,Glide glide,final Lifecycle lifecycle,//关键代码,这个是上面的activity.getLifecycle()FragmentManager childFragmentManager,boolean isParentVisible) {Util.assertMainThread();RequestManager result = getOnly(lifecycle);if (result == null) {LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);//关键代码result =factory.build(glide,glideLifecycle,//在这里面会创建RequestManager并把它加入glideLifecycle里面new SupportRequestManagerTreeNode(childFragmentManager),context);lifecycleToRequestManager.put(lifecycle, result);glideLifecycle.addListener(new LifecycleListener() {@Overridepublic void onStart() {}@Overridepublic void onStop() {}@Overridepublic void onDestroy() {lifecycleToRequestManager.remove(lifecycle);}});// This is a bit of hack, we're going to start the RequestManager, but not the// corresponding Lifecycle. It's safe to start the RequestManager, but starting the// Lifecycle might trigger memory leaks. See b/154405040if (isParentVisible) {result.onStart();}}return result;
}
}//LifecycleLifecycle.java
final class LifecycleLifecycle implements Lifecycle, LifecycleObserver {@NonNullprivate final Set<LifecycleListener> lifecycleListeners = new HashSet<LifecycleListener>();@NonNull private final androidx.lifecycle.Lifecycle lifecycle;LifecycleLifecycle(androidx.lifecycle.Lifecycle lifecycle) {this.lifecycle = lifecycle;lifecycle.addObserver(this);//关键代码,把自己嵌入到了activity.getLifecycle(),当生命周期函数有变化时就会通过它的onStart(),onStop(),onDestroy()}@OnLifecycleEvent(Event.ON_START)public void onStart(@NonNull LifecycleOwner owner) {for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {lifecycleListener.onStart();}}@OnLifecycleEvent(Event.ON_STOP)public void onStop(@NonNull LifecycleOwner owner) {for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {lifecycleListener.onStop();}}@OnLifecycleEvent(Event.ON_DESTROY)public void onDestroy(@NonNull LifecycleOwner owner) {for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {lifecycleListener.onDestroy();}owner.getLifecycle().removeObserver(this);}@Overridepublic void addListener(@NonNull LifecycleListener listener) {lifecycleListeners.add(listener);if (lifecycle.getCurrentState() == State.DESTROYED) {listener.onDestroy();} else if (lifecycle.getCurrentState().isAtLeast(State.STARTED)) {listener.onStart();} else {listener.onStop();}}@Overridepublic void removeListener(@NonNull LifecycleListener listener) {lifecycleListeners.remove(listener);}
}LifecycleLifecycle把会把RequestManager加入它的列表中,以便有生命周期函数变化时就通过它
LifecycleRequestManagerRetriever.java中LifecycleLifecycle glideLifecycle = new LifecycleLifecycle(lifecycle);//关键代码result =factory.build(glide,glideLifecycle,//在这里面会创建RequestManager并把它加入glideLifecycle里面new SupportRequestManagerTreeNode(childFragmentManager),context);
//RequestManagerRetriever.java中的RequestManager工厂类
private static final RequestManagerFactory DEFAULT_FACTORY =new RequestManagerFactory() {@NonNull@Overridepublic RequestManager build(@NonNull Glide glide,@NonNull Lifecycle lifecycle,//关键代码@NonNull RequestManagerTreeNode requestManagerTreeNode,@NonNull Context context) {return new RequestManager(glide, lifecycle, requestManagerTreeNode, context);//关键代码}};public class RequestManagerimplements ComponentCallbacks2, LifecycleListener, ModelTypes<RequestBuilder<Drawable>> {public RequestManager(@NonNull Glide glide,@NonNull Lifecycle lifecycle,@NonNull RequestManagerTreeNode treeNode,@NonNull Context context) {this(glide,lifecycle,//关键代码treeNode,new RequestTracker(),glide.getConnectivityMonitorFactory(),context);
}// Our usage is safe here.
@SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
RequestManager(Glide glide,Lifecycle lifecycle,//关键代码RequestManagerTreeNode treeNode,RequestTracker requestTracker,ConnectivityMonitorFactory factory,Context context) {this.glide = glide;this.lifecycle = lifecycle;//关键代码this.treeNode = treeNode;this.requestTracker = requestTracker;this.context = context;connectivityMonitor =factory.build(context.getApplicationContext(),new RequestManagerConnectivityListener(requestTracker));glide.registerRequestManager(this);if (Util.isOnBackgroundThread()) {Util.postOnUiThread(addSelfToLifecycle);} else {lifecycle.addListener(this);//关键代码}lifecycle.addListener(connectivityMonitor);defaultRequestListeners =new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());
}}

然后再由RequestManager的onStart(),onStop(),onDestroy()去通过相应的RequestTracker requestTracker和TargetTracker targetTracker做对应的处理

public class RequestManagerimplements ComponentCallbacks2, LifecycleListener, ModelTypes<RequestBuilder<Drawable>> {@SuppressWarnings("WeakerAccess")@Syntheticfinal Lifecycle lifecycle;@GuardedBy("this")private final RequestTracker requestTracker;@GuardedBy("this")private final TargetTracker targetTracker = new TargetTracker();
@Override
public synchronized void onStart() {resumeRequests();//关键代码targetTracker.onStart();//关键代码
}@Override
public synchronized void onStop() {pauseRequests();//关键代码targetTracker.onStop();//关键代码
}@Override
public synchronized void onDestroy() {targetTracker.onDestroy();//关键代码for (Target<?> target : targetTracker.getAll()) {clear(target);}targetTracker.clear();//关键代码requestTracker.clearRequests();//关键代码lifecycle.removeListener(this);//关键代码lifecycle.removeListener(connectivityMonitor);//关键代码Util.removeCallbacksOnUiThread(addSelfToLifecycle);glide.unregisterRequestManager(this);
}
}


总结:

总流程:Activity.getLifecycle()在LifecycleLifecycle构造函数里把LifecycleLifecycle this对象加入了Activity.getLifecycle(),LifecycleLifecycle对象传入RequestManager构造函数时,把RequestManager对象加入到了LifecycleLifecycle对象的监听列表里面,RequestManager对象又有RequestTracker和TargetTracker对象,有点饶,我写个抽象类(只为了看)

public class ComponentActivity{private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);public Lifecycle getLifecycle() {return mLifecycleRegistry;}//如上会通过Activity.getLifecycle().addObserver()方法加入到LifecycleLifecycle.this
}public cliass LifecycleLifecycle{@NonNullprivate final Set<LifecycleListener> lifecycleListeners = new HashSet<LifecycleListener>();@Overridepublic void addListener(@NonNull LifecycleListener listener) {lifecycleListeners.add(listener);}//LifecycleLifecycle会通过addListener()方法把RequestManager.this加入到lifecycleListeners@OnLifecycleEvent(Event.ON_START)public void onStart(@NonNull LifecycleOwner owner) {for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {lifecycleListener.onStart();//RequestManager.this在里面,会被通知到}}@OnLifecycleEvent(Event.ON_STOP)public void onStop(@NonNull LifecycleOwner owner) {for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {lifecycleListener.onStop();//RequestManager.this在里面,会被通知到}}@OnLifecycleEvent(Event.ON_DESTROY)public void onDestroy(@NonNull LifecycleOwner owner) {for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {lifecycleListener.onDestroy();//RequestManager.this在里面,会被通知到}owner.getLifecycle().removeObserver(this);}
}public class RequestManager implements LifecycleListener {private final RequestTracker requestTracker;private final TargetTracker targetTracker = new TargetTracker();@Overridepublic synchronized void onStart() {resumeRequests();targetTracker.onStart();}@Overridepublic synchronized void onStop() {pauseRequests();targetTracker.onStop();}@Overridepublic synchronized void onDestroy() {targetTracker.onDestroy();targetTracker.clear();requestTracker.clearRequests();}
}

相关文章:

新版Glide检测生命周期原理

本文章使用的是glide 4.15.1 public class RequestManagerRetriever implements Handler.Callback {rivate final LifecycleRequestManagerRetriever lifecycleRequestManagerRetriever;public RequestManagerRetriever(Nullable RequestManagerFactory factory, GlideExperim…...

Ansible的脚本-----playbook剧本【上】

目录 1.playbook剧本组成 2.playbook剧本实战演练 2.1 实战演练一&#xff1a;给被管理主机安装httpd服务 2.2 实战演练二&#xff1a;定义、引用变量 2.3 实战演练三&#xff1a;指定远程主机sudo切换用户 2.4 实战演练四&#xff1a;when条件判断 2.5 实战演练五&…...

sql注入学习与防护

一、SQL注入分类 SQL注入根据攻击方式的不同&#xff0c;可以分为以下几种类型&#xff1a; 数字型注入字符型注入报错注入布尔盲注时间盲注联合查询注入基于堆叠的查询注入 二、SQL注入流程 发现注入点猜测字段数确定显示字段获取数据库信息获取数据库中的表获取表中的字段获…...

饥荒dst联机服务器搭建基于Ubuntu

目录 一、服务器配置选择 二、项目 1、下载到服务器 2、解压 3、环境 4、启动面板 一、服务器配置选择 首先服务器配置需要2核心4G&#xff0c;4G内存森林加洞穴大概就占75% 之后进行服务器端口的开放&#xff1a; tcp:8082 tcp:8080 UDP:10888 UDP:10998 UDP:10999 共…...

AtCoder Beginner Contest 363

A - Piling Up 题意 不同的分数段有不同的^数量&#xff0c;Takahashi想要使得他的^数量增加&#xff0c;问他所需要的最少分数增幅。 思路 我们只需要找到下一阶段的下限。 a / 100 是本阶段 1 变成下一阶段&#xff0c;再 * 100变成下限&#xff0c;再与原来的相减即可…...

Protel DXP 面试题详解及参考答案(4万字长文)

解释Protel DXP的基本工作流程。 Protel DXP(现已更名为Altium Designer)是一款用于电子设计自动化(EDA)的软件,主要应用于印刷电路板(PCB)设计。其基本工作流程通常包括以下几个阶段: 项目创建与配置: 开始一个新的设计项目时,首先需要创建一个项目文件,在这个文件…...

雪花算法 集群uid重复问题 uid-generator-spring-boot-starter

1、在生成环境 在某个业务使用该插件生成uid,由于业务整合了 mybatis-plus模块 2、该业务是分部署集群部署以及使用的多线程获取uid&#xff0c;使用中发现唯一建冲突&#xff0c;生成的uid有重复。 然后查看日志发现 workerId 始终为0 怀疑是生成workerId出了问题。 查看跟…...

【AutoDL】AutoDL+Xftp+Xshell+VSCode配合使用教程

身边没有显卡资源或不足以训练模型时&#xff0c;可以租赁服务器的显卡。 1、AutoDL Step :注册账号->选择显卡->选择环境->开机启动 1.1 首先打开AutoDL官网&#xff0c;注册账号 1.2 租赁自己想要的显卡资源 1.3 选择基础环境。 此处&#xff0c;我们让其自动配置…...

使用minio cllient(mc)完成不同服务器的minio的数据迁移和mc基本操作

minio client 前言使用1.拉取minio client 镜像2.部署mc容器3.添加云存储服务器4.迁移数据1.全量迁移2.只迁移某个桶3.覆盖重名文件 5.其他操作1.列出所有alias、列出列出桶中的文件和目录1.1.列出所有alias1.2.列出桶中的文件和目录 2.创建桶、删除桶2.1.创建桶2.2.删除桶 3.删…...

Vue3分段控制器(Segmented)

效果如下图&#xff1a;在线预览 APIs Segmented 参数说明类型默认值必传block是否将宽度调整为父元素宽度&#xff0c;同时所有选项占据相同的宽度booleanfalsefalsedisabled是否禁用booleanfalsefalseoptions选项数据string[] | number[] | SegmentedOption[][]falsesize控…...

SpringSecurity如何正确的设置白名单

在SpringSecurity中,往往需要对部分接口白名单访问,而大部分在使用Security中就有一个误区,那就是免鉴权访问和白名单的区别。 大部分的Security文章包括官方文档给出免鉴权访问都是使用.permitAll()去对相应路径进行免鉴权访问,但实际上这仅仅只表示该资源不需要相应的权限访问…...

【Langchain大语言模型开发教程】评估

&#x1f517; LangChain for LLM Application Development - DeepLearning.AI 学习目标 1、Example generation 2、Manual evaluation and debug 3、LLM-assisted evaluation 4、LangChain evaluation platform 1、引包、加载环境变量&#xff1b; import osfrom dotenv imp…...

Python爬虫小项目实战

1.自动获取小说多个章节内容 2.获取英雄联盟里面的全部英雄 3. 简单地自动抽奖系统 4. 简单地点赞系统 5. 制作查询手机号工具 6. 制做登录系统 7. 操作excel办公自动化 8. 自动批量保存图片 9. 获取NBA数据 10. 获取彩票信息 11. 获取房地产信息 12. 获取小说…...

PHP Filesystem 简介

PHP Filesystem 简介 PHP 是一种广泛使用的开源服务器端脚本语言,特别适用于网页开发。在 PHP 中,Filesystem 是一个功能丰富的库,提供了一系列用于文件系统操作的函数。这些函数允许开发者读取、写入、修改和删除文件和目录,以及执行其他与文件系统相关的任务。 PHP Fil…...

源代码加密软件哪家好?五款企业级加密软件推荐

随着软件开发行业的快速发展&#xff0c;源代码作为核心资产&#xff0c;面临着越来越大的安全威胁。保护源代码不被泄露或盗用&#xff0c;是每个开发团队和企业都需要高度重视的问题。源代码加密软件通过对代码进行加密处理&#xff0c;确保其在传输和存储过程中保持机密性。…...

Redis常见的数据类型及操作方式

一、通用命令 1&#xff09;获取redis中所有key keys * 2&#xff09;删除一个或多个key del key1 key2 ... 3&#xff09;判断key是否存在 exists key 4&#xff09;给key添加过期时间 expire key time 5&#xff09;查看key剩余过期时间 ttl key 6) 查看redis内存…...

谷粒商城实战笔记-55-商品服务-API-三级分类-修改-拖拽数据收集

文章目录 一&#xff0c;拖拽后结点的parentCid的更新二&#xff0c;拖拽后结点的父节点下所有结点的sort排序属性的变化更新排序的逻辑代码分析 三&#xff0c;拖拽后结点及其子节点catLevel的变化判断是否需要更新 catLevel获取拖动后的新节点 更新 catLevel完整代码 这一节的…...

AI绘画入门实践|Midjourney:使用 --seed 制作情侣头像与漫画

在 Midjourney 中&#xff0c;seed 是指一个种子&#xff0c;用于生成图像时的起点或基础。 使用格式&#xff1a;--seed 获取的seed值 获取 seed 值 使用 seed 生成图像 a cute boys avatar, background with blue sky and white cloud, Ghibli Studio style, Hayao Miyazaki…...

笔记:Enum中FlagsAttribute特性的用法

一、目的&#xff1a;分享Enum中FlagsAttribute特性的用法 在C#中&#xff0c;Enum&#xff08;枚举&#xff09;类型可以使用[Flags]属性来表示一个枚举可以存储多个值。这是通过按位运算符&#xff08;如|&#xff08;或&#xff09;和&&#xff08;与&#xff09;&#…...

QWidget如何切换ui

在Qt中&#xff0c;QWidget及其子类用于构建图形用户界面。如果你想要在不同的UI之间切换&#xff0c;可以使用QStackedWidget&#xff0c;它可以管理一组QWidget&#xff0c;并且每次只显示其中一个。 以下是一个简单的例子&#xff0c;展示如何使用QStackedWidget切换UI&…...

终极指南:10分钟搞定网易云音乐NCM加密文件转换

终极指南&#xff1a;10分钟搞定网易云音乐NCM加密文件转换 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换&#xff0c;Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 还在为网易云音乐的加密NCM文件无法在其他播放器使…...

3小时掌握拼多多数据采集:Scrapy框架实战指南

3小时掌握拼多多数据采集&#xff1a;Scrapy框架实战指南 【免费下载链接】scrapy-pinduoduo 拼多多爬虫&#xff0c;抓取拼多多热销商品信息和评论 项目地址: https://gitcode.com/gh_mirrors/sc/scrapy-pinduoduo 对于电商数据分析和市场研究从业者而言&#xff0c;获…...

革命性Android性能监控平台ArgusAPM:一站式解决移动应用性能难题

革命性Android性能监控平台ArgusAPM&#xff1a;一站式解决移动应用性能难题 【免费下载链接】ArgusAPM Powerful, comprehensive (Android) application performance management platform. 360线上移动性能检测平台 项目地址: https://gitcode.com/gh_mirrors/ar/ArgusAPM …...

如何用Xournal++高效管理数字笔记:5个实用场景完全指南

如何用Xournal高效管理数字笔记&#xff1a;5个实用场景完全指南 【免费下载链接】xournalpp Xournal is a handwriting notetaking software with PDF annotation support. Written in C with GTK3, supporting Linux (e.g. Ubuntu, Debian, Arch, SUSE), macOS and Windows 1…...

零售AI实战:Ostrakon-VL-8B应用案例,智能分析商品种类、数量与陈列效果

零售AI实战&#xff1a;Ostrakon-VL-8B应用案例&#xff0c;智能分析商品种类、数量与陈列效果 1. 零售视觉分析的挑战与机遇 在零售行业&#xff0c;商品陈列和库存管理是影响销售的关键因素。传统的人工巡检方式存在效率低、成本高、主观性强等问题。以一个中型超市为例&am…...

JS手撕:DOM操作 浏览器API高频场景详解

在前端开发中&#xff0c;我们经常会遇到一些重复且基础的需求——比如解析URL参数、给大量元素绑定点击事件、实现图片懒加载等。这些功能看似简单&#xff0c;但写得不够严谨就容易出现bug&#xff08;比如中文参数乱码、事件绑定冗余、滚动加载卡顿&#xff09;。 今天就整理…...

Linux 软件安装没你想的那么简单:为什么有的软件能直接跑,有的非装不可?

Linux 软件安装没你想的那么简单&#xff1a;为什么有的软件能直接跑&#xff0c;有的非装不可&#xff1f; 很多人刚接触 Linux 的时候&#xff0c;对“安装软件”这件事有点迷。 在 Windows 上&#xff0c;大家已经习惯了&#xff1a; 双击一个 exe一路“下一步”软件出现在桌…...

从零到一:手把手教你用cam_lidar_calibration标定自己的VLP-16与海康相机(附完整ROS Bag录制技巧)

从零到一&#xff1a;VLP-16激光雷达与海康相机联合标定实战指南 当激光雷达点云与相机图像在自动驾驶系统中完美对齐时&#xff0c;传感器融合的魔法才真正开始。作为机器人感知的核心环节&#xff0c;标定质量直接决定了后续目标检测、SLAM等模块的精度上限。本文将手把手带您…...

Pixel Language Portal惊艳案例:用Hunyuan-MT-7B将甲骨文识别结果实时译为多语种学术注解

Pixel Language Portal惊艳案例&#xff1a;用Hunyuan-MT-7B将甲骨文识别结果实时译为多语种学术注解 1. 项目概览&#xff1a;当古老文字遇见现代AI Pixel Language Portal&#xff08;像素语言跨维传送门&#xff09;是一款基于腾讯Hunyuan-MT-7B大模型构建的创新翻译工具。…...

拓世AI决策系统白皮书

拓世AI决策系统白皮书——基于六元结构的双环自适应决策架构版权与所有权声明本技术系统所有知识产权归拓世网络技术开发室&#xff08;Tuoshi Network Technology Development Studio&#xff09;独家所有。本系统由拓世网络技术开发室唯一技术开发者独立完成&#xff0c;未接…...