Jetpack Navigation 的工作流程涉及多个核心类和复杂的交互,以下是从源码角度对其主要工作流程的分析:
一、初始化阶段
-
NavHostFragment
的创建:- 当在布局文件中使用
<androidx.fragment.app.FragmentContainerView android:name="androidx.navigation.fragment.NavHostFragment"/>
时,系统会实例化NavHostFragment
。这个类是NavHost
的具体实现,它负责管理导航图中的各个片段(Fragment)的显示和切换。 - 在
NavHostFragment
的onCreate
方法中,会初始化一些重要的成员变量,如NavController
和LifecycleOwner
等。
- 当在布局文件中使用
-
NavController
的获取:NavHostFragment
通过findNavController()
方法获取NavController
实例。这个方法会遍历视图层次结构,查找最近的NavControllerProvider
,通常是NavHostFragment
自身。NavController
是导航的核心控制对象,它负责处理导航操作,如导航到特定目的地、返回上一个目的地等。
-
导航图的加载:
NavController
在初始化过程中会加载导航图。导航图通常是一个 XML 文件,定义了应用的导航结构,包括各个目的地(Fragment)以及它们之间的连接关系。NavInflater
类负责解析导航图 XML 文件,并创建对应的NavDestination
对象树。每个NavDestination
代表导航图中的一个目的地,如一个 Fragment。
二、导航操作阶段
-
导航请求的发起:
- 当用户触发一个导航操作时,比如点击按钮触发导航到另一个 Fragment,通常会调用
NavController.navigate()
方法。这个方法接收一个动作 ID,该 ID 在导航图中定义了从当前目的地到目标目的地的导航动作。 - 例如:
navController.navigate(R.id.action_fragment1_to_fragment2);
- 当用户触发一个导航操作时,比如点击按钮触发导航到另一个 Fragment,通常会调用
-
NavController
的处理:NavController
接收到导航请求后,会根据当前的导航状态和导航图来确定如何执行导航操作。- 它会遍历导航图中的目的地树,找到当前位置和目标位置之间的路径。然后,根据导航动作的类型(如替换、弹出到目标等),决定如何切换 Fragment。
-
FragmentNavigator
的作用:NavController
通常会使用不同的Navigator
实现来执行具体的导航操作。对于 Fragment 导航,会使用FragmentNavigator
。FragmentNavigator
负责在NavHostFragment
中管理 Fragment 的显示和切换。它会创建、显示和移除 Fragment,以实现导航效果。
-
Fragment 的切换:
FragmentNavigator
会根据导航动作的要求,创建目标 Fragment 的实例,并将其添加到NavHostFragment
的FragmentManager
中。- 如果是替换操作,会先移除当前显示的 Fragment,然后添加目标 Fragment。如果是弹出操作,会根据回退栈的状态进行相应的 Fragment 移除操作。
三、生命周期管理阶段
-
与
LifecycleOwner
的集成:NavHostFragment
实现了LifecycleOwner
接口,这使得它可以感知自身的生命周期变化。NavController
会根据NavHostFragment
的生命周期状态来调整导航操作。- 例如,当
NavHostFragment
进入暂停状态时,NavController
可能会暂停一些导航相关的操作,以避免不必要的资源消耗。
-
回退栈的管理:
NavController
维护了一个导航回退栈,用于记录用户的导航历史。当用户按下返回键时,NavController
会根据回退栈的状态,弹出当前显示的 Fragment,显示上一个 Fragment。FragmentNavigator
会在 Fragment 的切换过程中正确地管理回退栈,确保回退操作符合预期。
总之,Jetpack Navigation 通过精心设计的类和接口,实现了从导航图的加载、导航请求的处理到 Fragment 的切换和生命周期管理的完整工作流程。这种设计使得应用的导航逻辑更加清晰、可维护,并且易于与其他 Jetpack 组件集成。