Android Fragment使用NavArgs从C跳转B出现NullPointerException问题
问题原因分析
两种返回操作的本质差异
- 调用
activity?.onBackPressed()/findNavController().popBackStack():属于回退栈出栈操作,会销毁栈顶的Fragment C,恢复之前已经存在的Fragment B实例,这个B实例的Arguments是从Fragment A跳转时传入的,包含完整的currentState参数,因此不会报错。 - 调用
findNavController().navigate(R.id.action_fragment_c_to_fragment_b):属于新建目标实例入栈操作,会重新创建一个Fragment B实例压入回退栈,你定义的该跳转action没有携带Fragment B要求的必填currentState参数,新B实例的args.currentState为空,访问name属性就会抛出空指针异常。
额外补充说明
如果是直接传入action id的方式执行跳转,导航组件不会做编译期参数校验,很容易出现漏传参数的问题;如果使用自动生成的CFragmentDirections类构造跳转参数,缺少必填参数时编译阶段就会报错,可以提前规避这类问题。
修复方案
你可以根据业务需求选择以下任意一种方案:
- 若需求是回到之前打开的Fragment B实例:直接用回退栈出栈操作代替主动跳转即可
// Fragment C中调用,和onBackPressed效果一致 findNavController().popBackStack()
- 若需求确实需要从C新建B实例跳转:
- 方式一:跳转时携带
currentState参数,你可以在A跳B、B跳C时把currentState也传递给C,C跳转B时再回传参数
// Fragment C跳转B代码示例 val direction = CFragmentDirections.actionFragmentCToFragmentB( currentState = 你保存在C中的currentState对象 ) findNavController().navigate(direction)- 方式二:在导航图中给Fragment B的
currentState参数设置默认值,适合参数非必须的场景
注意设置默认值为null后,后续访问<argument android:name="currentState" app:argType="你的Parcelable类全路径" android:defaultValue="@null" />args.currentState时要做好空判断。 - 方式一:跳转时携带
内容的提问来源于stack exchange,提问作者onesector
相关产品推荐
相关产品推荐

