Android Navigation Component中destination与action导航的区别是什么
两种导航方式的具体区别
我们以Kotlin代码示例做参照:
- 直接导航到目的地:调用方式为
navController.navigate(R.id.fragmentB),直接传入目标目的地的资源ID - 通过Action跳转:调用方式为
navController.navigate(R.id.action_A_B),传入的是两个目的地之间定义的导航路径ID
二者核心差异如下:
- 绑定对象不同:直接导航和目标目的地强绑定,而Action绑定的是「从A到B」这条导航路径,和具体目的地没有直接耦合。
- 配置复用逻辑不同:直接导航如果要配置转场动画、回退栈操作(比如
popUpTo)、singleTop启动模式等效果,每次调用都要手动传入NavOptions参数,很容易出现同个跳转不同场景配置不一致的问题;Action的所有导航配置都可以提前写在导航图的<action>标签里,所有触发该Action的跳转都会自动套用配置,不需要重复编写业务代码。 - 后续维护成本不同:如果后续需要修改Fragment A的跳转目标为Fragment C,直接导航的写法需要修改所有业务代码中调用
navigate(R.id.fragmentB)的位置;而Action的写法只需要修改导航图中action_A_B的app:destination属性为Fragment C的ID即可,业务侧代码完全不需要改动。 - 参数校验能力不同:直接导航传参没有编译期校验,漏传必填参数、传错参数类型只会在运行时抛出异常;如果搭配Safe Args插件使用,Action会自动生成对应的参数类,跳转时的参数合法性会在编译期就完成校验,提前发现问题。
设置Action的实际作用
- 统一管理导航行为:将同一条导航路径的所有配置(动画、回退栈规则、启动模式、参数规则)聚合在导航图中,减少冗余代码,保证同个导航行为在全应用内的一致性。
- 降低代码耦合:业务层只需要关心触发什么导航动作,不需要关心最终的目标目的地,导航路径的调整可以完全在导航图中完成,和业务代码解耦。
- 提升参数传递安全性:搭配Safe Args实现编译期参数校验,避免运行时传参错误导致的崩溃。
- 适配多场景触发需求:Action可以和深层链接(DeepLink)绑定,同一条导航路径既可以由应用内代码触发,也可以由外部链接、系统通知等场景触发,行为完全一致,不需要额外做适配。
- 支持多模块导航:多模块项目中,子模块不需要依赖其他模块的目的地资源ID,只需要依赖公共的Action定义即可实现跨模块导航,避免模块间的资源耦合。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

