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

Android开发笔记 :理解Fragment

Android开发笔记:理解Fragment

在这里插入图片描述

导言

本篇文章产生的原因很简单,就是我在了解Android Jetpack中的Lifecycle框架时发现Lifecycle具体时间和状态的更新都是由一个名为ReportFragment的Fragment来跟踪的,为了更好的了解Fragment是如何追踪Activity生命周期状态的变化我们有必要对Fragment组件进行更深入的探讨。

Fragment管理器

首先我们要探讨的就是Fragment管理器(FragmentManager),我们在进行动态地加载和移除Fragment的操作时都需要借助这个Fragment管理器来开启事务,提交请求。Fragment的管理与ViewGroup与View的关系类似,一个Fragment既是上一个父Fragment的子Fragment,又是下一个子Fragment的父Fragment。而每一个父Fragment都有一个FragmentManager来管理其子Fragment。

我们以Google官网上的一张图为例子:
在这里插入图片描述
其中绿色的部分代表的是顶级Activity的布局界面,蓝色部分就是Activity中的Fragment容器了,白色的部分是示例中的最底层的Fragment。在Example 1中Fragment容器中装有两个子Fragment,而每一个父Fragment都有一个FragmentManager,所以例子一种的包含关系和管理关系如下所示:
在这里插入图片描述
对于中间第二级的Fragment,我们即可以通过getParentFragmentManager来获取管理其自身的FragmentManager,还可以通过getChildFragmentManager来获取其管理的Manager。

Fragment事务

所谓的事务,我会把它理解为是一组关于Fragment的操作,我们可以通过beginTransaction方法来开启一个事务,通过这个事务我们可以实现Fragment的添加,移除,替换等操作。当一切操作都添加完毕后我们可以通过commit方法将当前事务给提交。不过,被提交的事务并不会被马上执行,相反的,它会等待主线程,一旦它可以被执行了才会被执行。当然了,我们也可以通过commitNow方法来马上触发事务,不过需要说明的是commitNow是和addToBackStack不兼容的,也就是说一旦你调用了commitNow方法就不能再使用返回栈了。还有一种方法就是调用executePendingTransactions方法,这个方法会执行所有被挂起的事务。

触发事务可能会引起Fragment的生命周期的变化,具体来说,当一个Fragment实例被执行add操作后,它会进入到STARED状态之中去。

通过事务我们还可以限制Fragment的生命周期,调用setMaxLifecycle方法可以为Fragment设置最大的生命周期,所谓的大和小就是靠近运行状态(Resume)的距离,距离运行状态越近生命周期越大。

Fragment的生命周期

接下来我们要谈到的是Fragment的生命周期,每一个Fragment都有其生命周期。Fragment实现了LifecycleOwner接口,说明Fragment也可以使用Lifecycle进行检测。实际上,Activity的LifecycleOwner状态的变化也是通过一个特殊的Fragment来进行跟踪的。除了使用Lifecycler之外,Fragment与Activity一样本身就带有关于生命周期的回调方法。

还需要说明的是Fragment的视图也单独有一个Lifecycle,它独立于Fragment的Lifecycle的,Fragment会为其视图维护一个LifecycleOwner,我们可以通过 getViewLifecycleOwner() 或 getViewLifecycleOwnerLiveData()进行访问。
在这里插入图片描述

生命周期之下的Fragment和Fragment管理器

具体来说Fragment的生命周期是由其FragmentManager所管理的,在实例化Fragment之后,它会从INITIALIZED状态开始,并且将其添加进入FragmentManager之中,FragmentManager负责确定ragment应该是处于哪个状态的。而且FragmentManager还会负责Fragment与其宿主Activity的附加和分离。将 Fragment 添加到 FragmentManager 并附加到其宿主 Activity 后,系统将调用 onAttach() 回调。此时,该 Fragment 处于活跃状态,FragmentManager 管理其生命周期状态。此时,findFragmentById() 等 FragmentManager 方法会返回此 Fragment。

在发生任何生命周期状态变更之前,系统都始终会调用 onAttach()在发生生命周期状态变更之后,系统始终都会调用 onDetach()

当Fragment被从FragmentManager之中移除并被分离之后会被触发其onDetach()方法,说明该Fragment已经不再处于活跃状态,并且我们无法通过findFragmentById()检索到。

Fragment生命周期状态与回调

在确定 Fragment 的生命周期状态时,FragmentManager 会考虑以下方面:

  • Fragment 的状态极限由其 FragmentManager 确定。Fragment 不能超过其 FragmentManager 的状态。
  • 作为 FragmentTransaction 的一部分,您可以使用 setMaxLifecycle() 在 Fragment 上设置生命周期状态极限。
  • Fragment 的生命周期状态绝对不能超过其父级。例如,父 Fragment 或 Activity 必须在其子 Fragment 之前启动。同样,子 Fragment 必须在其父 Fragment 或 Activity 之前停止。

这整个规则是很合理的,当然只有先启动了父Fragment才能启动子Fragment,下面便搬出Fragment生命周期转变的图,可以看到Fragment的生命周期和它的View的生命周期是不一样的
在这里插入图片描述
在Fragment发生状态改变的过程中系统会首先调用其新状态关联的生命周期回调,然后才会向Lifecycle发送Event事件触发Lifecycle框架下的回调方法。如果Fragment已经实例化的话,Fragment 的视图 Lifecycle 也会紧随其后向观察者发出此事件。

当Fragment到达了CREATED状态时就说明它已经被添加到了FragmentManager之中,并且已经调用了onAttach方法了。强烈建议将生命周期感知型组件与 Fragment 的 STARTED 状态相关联,因为该状态可确保 Fragment 的视图(如已创建)可用,并且可确保在 Fragment 的子 FragmentManager 上安全地执行 FragmentTransaction。如果 Fragment 的视图为非 null,在 Fragment 的 Lifecycle 转为 STARTED 后,Fragment 的视图 Lifecycle 会立即转为 STARTED。

当 Fragment 转为 STARTED 时,系统会调用 onStart() 回调。

Fragment 不再可见后,Fragment 及其视图的 Lifecycle 将转为 CREATED 状态,并向其观察者发出 ON_STOP 事件。不仅停止父 Activity 或 Fragment 会触发该状态转换,而且父 Activity 或 Fragment 保存状态也会触发该状态转换。此行为可保证在保存 Fragment 的状态之前调用 ON_STOP 事件。这使得 ON_STOP 事件成为能够安全地在子 FragmentManager 上执行 FragmentTransaction 的最后一个时间点。

如图所示,onStop() 回调与使用 onSaveInstanceState() 保存状态之间的顺序因 API 级别而异。对于 API 28 之前的所有 API 级别,在 onStop() 之前调用 onSaveInstanceState()。对于 API 28 及更高级别,调用顺序正好相反。
在这里插入图片描述

相关文章:

Android开发笔记 :理解Fragment

Android开发笔记:理解Fragment 导言 本篇文章产生的原因很简单,就是我在了解Android Jetpack中的Lifecycle框架时发现Lifecycle具体时间和状态的更新都是由一个名为ReportFragment的Fragment来跟踪的,为了更好的了解Fragment是如何追踪Activ…...

std::chrono获取当前秒级/毫秒级/微秒级/纳秒级时间戳

当前时间戳获取方法 先使用std::chrono获取当前系统时间,然后将当前系统时间转换为纪元时间std::time_t类型,之后使用std::localtime对std::time_t类型转换为本地时间结构体std::tm类型,最后使用strftime对时间进行格式化输出。 其中std::t…...

sh文件介绍及linux下执行

Shell脚本是一种用于自动化任务和系统管理的脚本语言。它允许用户通过命令行界面执行一系列命令,从而简化了重复性任务的处理过程。 以下是关于Shell脚本的一些基本概念: 1. Shell脚本通常以“.sh”扩展名保存,例如“script.sh”。 2. Shell…...

js-cookie使用 js深度克隆(判断引用类型是数组还是对象的方法)

cookie和深度拷贝的使用 1、js-cookie使用2、js深度克隆 1、js-cookie使用 前端的本地存储分为 localstorage、sesstionstorage、cookie 但是咱们有时候需要做7天免登录的需求时,选择 cookie 作为前端的本地存储是在合适不过的了 直接操作 cookie 可以, …...

[Pytorch]语义分割任务分类的实现

文章目录 [Pytorch]语义分割任务分类的实现 [Pytorch]语义分割任务分类的实现 假如我们定义了一个网络用于语义分割任务,这个网络简称为model() 语义分割任务要做的是: 对于一个图片输入input,大小为(B,C&#xff0c…...

测试网页调用本地可执行程序(续:带参数调用)

前篇文章介绍了网页调用本地可执行程序的方式,通过在注册表中注册命令,然后在网页中调用命令启动本地程序。如果需要传递参数,则需要在注册表命令中的command项中设置如下形式的值。 "XXXXXX\XXXXXXX.exe" "%1"&emsp…...

Carla自动驾驶模拟器安装和使用

Carla自动驾驶模拟器安装和使用 1 安装 ubuntu20.04安装carla0.9.11版本 步骤1:打开下面链接,点击第一个[Ubuntu] CARLA_0.9.11.tar.gz carla-0.9.11源码下载 步骤2:下载完解压到/opt目录下 我的话是先在下载目录上提取解压,然…...

【每日一题】1539. 第 k 个缺失的正整数

1539. 第 k 个缺失的正整数 - 力扣(LeetCode) 给你一个 严格升序排列 的正整数数组 arr 和一个整数 k 。 请你找到这个数组里第 k 个缺失的正整数。 示例 1: 输入:arr [2,3,4,7,11], k 5 输出:9 解释:缺失…...

AI-Chat,一款集全网ai功能的应用(附下载链接)

AI-Chat是一款综合性的聊天机器人,集成了多种先进的模型和功能。它采用了GPT4.0、联网版GPT和清华模型等多种模型,使得其具备更强大的语言处理能力。同时,AI-Chat还融合了AI绘画模型,例如Stable Diffusion绘画、文生图、图生图、艺…...

3、靶场——Pinkys-Place v3(3)

文章目录 一、获取flag41.1 关于SUID提权1.2 通过端口转发获取setuid文件1.3 运行pinksecd文件1.4 利用nm对文件进行分析1.5 构建payload1.6 Fire 二、获取flag52.1 生成ssh公钥2.2 免密登录ssh2.3 以pinksecmanagement的身份进行信息收集2.4 测试程序/usr/local/bin/PSMCCLI2.…...

什么是 AirServer?Mac专用投屏工具AirServer 7 .27 for Mac中文破解版百度网盘下载

AirServer 7 .27 for Mac中文免费激活版是一款Mac专用投屏工具,能够通过本地网络将音频、照片、视频以及支持AirPlay功能的第三方App,从 iOS 设备无线传送到 Mac 电脑的屏幕上,把Mac变成一个AirPlay终端的实用工具。 目前最新的AirServer 7.2…...

MapStruct介绍以及VO、DTO、PO、DO的区别

文章目录 一.基本概念1.1VO**(Value Object)值对象**1.2DTO**(Data Transfer Object)数据传输对象**1.3 PO**(Persistant Object)持久对象**等同于Entity,这俩概念是一致的 或DO1.4 **BO&#x…...

记一次hyperf框架封装swoole自定义进程

背景 公司准备引入swoole和rabbitmq来处理公司业务。因此&#xff0c;我引入hyperf框架&#xff0c;想用swoole的多进程来实现。 自定义启动服务封装 <?php /*** 进程启动服务【manager】*/ declare(strict_types1);namespace App\Command;use Swoole; use Swoole\Proce…...

多输入多输出 | MATLAB实现GA-BP遗传算法优化BP神经网络多输入多输出

多输入多输出 | MATLAB实现GA-BP遗传算法优化BP神经网络多输入多输出 目录 多输入多输出 | MATLAB实现GA-BP遗传算法优化BP神经网络多输入多输出预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 多输入多输出 | MATLAB实现GA-BP遗传算法优化BP神经网络多输入多输出…...

李宏毅机器学习笔记-transformer

transformer是什么呢&#xff1f;是一个seq2seq的model。具体应用如上图所示&#xff0c;输入和输出的序列长度不固定&#xff0c;由model自己决定。 语音翻译指的是&#xff0c;直接输入一段语音信号&#xff0c;例如英文&#xff0c;输出的直接是翻译之后的中文。 seq2seq如…...

基于Java的酒店管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...

Go语言的单元测试与基准测试详解

文章目录 单元测试基准测试 单元测试 以一个加法函数为例&#xff0c;对其进行单元测试。 首先编写add.go文件&#xff1a; //add.go package mainfunc add(a, b int) int {return a b }其次编写add_test.go文件&#xff0c;在go语言中&#xff0c;测试文件均已_test结尾&a…...

【多态】为什么析构函数的名称统一处理为destructor?

析构函数的名称统一处理为destructor的目的是为了解决析构函数的重写。 而这又引出了一个问题&#xff1a;为什么要进行析构函数的重写&#xff1f; 是为了下面这种情况&#xff1a; class Person { public:~Person() { cout << "~Person" << endl; } }…...

6.4 Case Studies - A Simple Logging Archive Class

下面这段内容介绍了一个示例&#xff0c;目的是帮助澄清"归档概念&#xff08;Archive Concept&#xff09;"的用法&#xff0c;以便用户可以实现自己的归档类。simple_log_archive.hpp 实现了一个简单但实用的归档类&#xff0c;用于将任何可序列化类型以可读的格式…...

【深度学习实验】前馈神经网络(九):整合训练、评估、预测过程(Runner)

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. __init__(初始化) 2. train(训练) 3. evaluate(评估) 4. predict(预测) 5. save_model 6. load_model 7. 代码整合 一、实验介绍 二、实验环境 本系列实验使用…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...