【背上Jetpack之Fragment】从源码角度看 Fragment 生命周期 AndroidX Fragment1.2.2源码分析

本文深入探讨AndroidX Fragment 1.2.2的生命周期,通过源码分析如何在Activity生命周期中影响Fragment,以及Fragment的生命周期自治。文章引导读者理解FragmentTransaction提交后的生命周期流程,以及如何通过FragmentManager和FragmentTransaction操作Fragment。同时,文章指出Fragment的生命周期与Activity紧密关联,但也有自身的状态管理和调用链。
摘要由CSDN通过智能技术生成

系列文章

【背上Jetpack】Jetpack 主要组件的依赖及传递关系

【背上Jetpack】AdroidX下使用Activity和Fragment的变化

【背上Jetpack之Fragment】你真的会用Fragment吗?Fragment常见问题以及androidx下Fragment的使用新姿势

前言

笔者看过不少源码分析类的文章,动辄贴上大段代码,这种方式很容易打断读者的思路,所以很多时候看过这类文章感叹好文好文,却感觉什么都没记住,亦或者默默加入收藏却不知何时能去细心地研读。

所以本文不会过多介绍源码的细节,更多地是抛砖引玉,如果您看过本文后能够跟着本文的思路自己翻一下源码相信您就不会有我上述的体验了。

本文默认您已对 fragment 的生命周期有所了解,并清楚fragment的缘起与职责。这部分基础内容可移步 fragment 官方文档

也即本文不会介绍 “what”,而是介绍 “how” 并且探讨一下 “why”

这里贴一下 androidx fragment 源码地址

androidx fragment 官方源码地址

本文基于 androidx fragment 1.2.2 源码分析

implementation "androidx.fragment:fragment-ktx:1.2.2"

本文主要介绍fragment的启动流程,其他内容例如返回栈,会后续更新,敬请关注。欢迎在评论区下讨论。本文demo

既然我们都知道 “what”,不妨我们来思考一下 “how”

分析前的思考

请大家思考一个问题,我们知道fragment 的生命周期是与其宿主 activity 的生命周期息息相关的,也即 activity 的每次生命周期回调都会引发每个fragment的类似回调。

那么,如果让我们来实现这样的操作,应该怎么做?

猜测:在activity每个生命周期的节点,去操作fragment,让其执行相应的生命周期方法。

思路有了,下面进行一些细节的确认。

  1. activity 要能操作 fragment,fragment 亦可操作 fragment,所以需要抽象出一个管理 fragment 的模型
  2. activity 操作 fragment 的一系列动作,应该是互为可逆一组操作。例如添加 fragment 后,也应能移除 fragment
  3. activity 对 fragment 的每组操作不应是单一的,例如可以在一次操作中在 activity 不同位置添加两个 fragment,同时该操作还应满足 2 ,具有可逆性

对于第一条,我们抽象出一个可以管理 fragment 的模型,加入上下级的关系,即 activity 可管理其内部的 fragment,fragment 亦可管理其内部的 fragment。因此 fragment 同时充当着管理者与被管理者两种角色

对于后两条,相信在大学学过数据库的人会想到一种结构:事务(Transaction)

事务是指一组原子性的操作,这些操作是不可分割的整体,要么全完成,要么全不完成,完成后可以回滚到完成前的状态

因此,fragment 中两个最重要的概念出现了,FragmentManagerFragmentTransaction

FragmentManager 封装着对 fragment 操作的各种方法,addFragment removeFragment 等等,而 FragmentActivity 通过 FragmentController 来操作 FragmentManager

FragmentTransaction 封装对 fragment 容器进行的 fragment 操作,例如在容器1内添加一个 fragment,同时在容器2内替换fragment。

它们均为抽象类,需要具体的实现类。

FragmentManager 的实现类为 FragmentManagerImpl,其内部逻辑已全部移至 FragmentManager 中,是个空实现。

FragmentTransaction 的实现类为 BackStackRecord ,其内部引用了 FragmentManager 的实例 ,同时重写了父类的 四个 commit 相关的方法。

看似最简单的启动流程

现在让我们看一部分代码,平时在activity中我们是这样填充一个fragment的

 override fun onCreate(savedInstanceState: Bundle?) {
   
        super.onCreate(savedInstanceState)
        //避免旋转屏幕等场景 fragment 重叠的问题
        if (savedInstanceState == null) {
   
            supportFragmentManager//步骤1
                .beginTransaction()//步骤2
                .add(R.id.container, BlankFragment.newInstance())//步骤3
                .commitNow()//步骤4
        }
 }
  • 步骤1,实例化 FragmentManagerImpl 对象 (内部经历了一些转换,详情参见源码或查看demo注释)

  • 步骤2,实例化 BackStackRecord对象,并在构造器中传入 FragmentManager 实例

  • 步骤3,调用事务方法,对 fragment 容器进行相应的操作,本例表示在 id 为 container 容器内添加 BlankFragment

  • 步骤4,提交事务,交于 FragmentManager 处理

在 terminal 敲入 adb shell setprop log.tag.FragmentManager VERBOSE 可开启FragmentManager的日志功能,过滤 FragmentManager ,日志如下:

单fragment启动日志-onCreate

绿色部分为笔者手动添加的log,灰色和蓝色部分为 fragment 源码中的log

根据日志显示的流程,我们的猜测看似是正确的,“在 activity 每个生命周期的节点,去操作 fragment ,让其执行相应的生命周期方法”

其实这里是有干扰的,因为我们是在activity 的 onCreate 方法里 创建并提交 FragmentTransaction ,如果在 onResume 里调用呢?

单fragment启动日志-onResume

WTF!

或许,我们的猜测有问题?看似调用 commitNow 后 fragment 的生命流程是自发进行的

那如果我们把调用挪到 onPause 呢?

打开 activity 并按下 home 键

单fragment启动日志-onPause

我知道好奇的读者会尝试在 onStop 中尝试一下,有惊喜。手动滑稽。

从这几段日志上来看,fragment 在提交事务后会自发进入自己的生命周期流程,而当其宿主 activity 生命周期发生变化时,fragment 的生命周期也跟随变化。

如果这么说比较抽象的话,我们可以看在 onPause 中显示fragment 的日志,当 Fragment 进入 onStart 生命周期后,如果是正常流程应该进入 onResume,但由于按下 home 键 activity进入onStop,fragment 也进入了 onStop 状态

因此,我们将之前的猜测进行扩展:

  1. 在activity每个生命周期的节点,去操作fragment,让其执行相应的生命周期方法
  2. FragmentTransaction 被提交后 fragment 会进入自己的生命周期流程,但受 1 约束

那么我们的源码解读就从两个方向入手

Activity 操作 Fragment 生命周期

activity 是通过 FragmentController 操作 FragmentManager 进而操作 fragment 的。

具体点就是在 activity 各个生命周期节点通过调用 FragmentController 中的各个 dispatch- 方法进而调用 FragmentManager 中的各个 dispatch- 方法

//FragmentActivity.java
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

//以下代码省略部分逻辑
@Override
### 回答1: androidx.fragment.app.fragmentAndroid Jetpack中的一个类,用于创建和管理Fragment。它是一个抽象类,需要通过继承来创建具体的FragmentFragmentAndroid应用程序中的一部分,可以在Activity中嵌入多个Fragment,实现更加灵活的UI设计和交互。使用androidx.fragment.app.fragment可以方便地管理Fragment生命周期、UI布局和交互逻辑。 ### 回答2: androidx.fragment.app.fragmentAndroid开发中Fragment组件的一个类,它是在Android Support Library中提供的,早期的Android版本并没有原生的Fragment组件,需要通过Support Library来实现。 Fragment是一种可重用的UI组件,可以看做是Activity中的一部分,可以在同一个Activity中切换多个Fragment来实现不同的UI布局和交互方式。相比于Activity,Fragment具有更灵活的UI组合和生命周期管理的能力,可以实现更复杂的UI交互设计。 androidx.fragment.app.fragment类提供了一些重要的方法,比如onCreateView(),onStart(),onStop()等,这些方法可以被开发者重写来实现自定义的UI布局和逻辑处理。同时,Fragment也具有独立的生命周期,可以和Activity共同管理生命周期,确保Fragment和它所依附的Activity在同一生命周期内都能正确地运行。 使用androidx.fragment.app.fragment可以让开发者实现更加灵活的UI设计和交互方式,为Android应用的开发提供了更加丰富的工具和手段。同时,由于androidx.fragment.app.fragment已经被纳入到AndroidX库中,可以很好地与其他库和框架进行集成,具有更好的兼容性和稳定性。 ### 回答3: androidx.fragment.app.fragmentAndroid开发中的一个重要组件,用于实现应用程序的界面模块化。 fragment可以看作是Activity中的一个UI组件,而且可以重复使用,使得应用程序更容易维护和扩展。通过将Activity中的界面切分成多个小模块,来实现更高效的UI重用,并且避免同时管理多个Activity带来的复杂性。 在使用fragment时,需要在activity的布局文件中定义fragment的视图容器。然后,在activity中通过FragmentManager来操作fragment,包括添加、删除、替换、隐藏、显示等操作。 一个fragment可以拥有自己的生命周期,可以响应用户事件,可以与其它fragment通信。可以使用fragment之间的接口来传递信息。同时,可以通过FragmentTransaction来管理fragment的状态,该对象可以执行添加、删除、替换等操作。如果需要在Fragment之间进行数据交换,可以使用Bundle来进行传递。 androidx.fragment.app.fragmentAndroid开发中常用的场景包括: 1. 在单个activity中使用多个fragment来展示复杂的UI。 2. 在多个activity中复用相同的界面模块,实现UI样式和功能的统一。 3. 将UI逻辑切分成不同的Fragment,便于团队协作和模块化开发。同时,也便于将应用程序进行抽象和拆分,使得应用程序更加易于维护和扩展。 总之,androidx.fragment.app.fragmentAndroid开发中非常重要的一个组件,可以用于实现复杂的界面布局和应用程序的模块化开发。通过合理的应用,可以提高开发效率和用户体验,同时也可以增加应用程序的可维护性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值