打开FragmentAddDriver时报“目标片段不属于当前FragmentManager”问题排查
问题场景
我搭建了一个简单的片段交互场景,涉及三个Fragment的递进跳转:
相关代码逻辑如下:
ActivityHaupt 添加 FragmentHaupt 的逻辑
final FragmentHaupt fragment = new FragmentHaupt(); final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.frameLHaupt, fragment, null); transaction.disallowAddToBackStack(); transaction.commit();
FragmentHaupt 跳转 FragmentViewP 的逻辑
FragmentViewPfragment2 = new FragmentViewP(); fragment2.setTargetFragment(FragmentHaupt.this, 12); //AppConstant.FRAGMENT_CODE = 12 FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.addToBackStack(null); fragmentTransaction.replace(R.id.frameLHaupt, fragment2); fragmentTransaction.commit();
FragmentViewP 跳转 FragmentAddDriver 的逻辑
FragmentAddDriver ldf = new FragmentAddDriver (); Bundle args = new Bundle(); args.putString("firstname", vName.getText().toString()); args.putString("lastname", nName.getText().toString()); args.putString("drivername", dName.getText().toString()); ldf.setArguments(args); ldf.setTargetFragment(FragmentHaupt.newInstance("firstP","lastP"), 12); FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.addToBackStack(null); fragmentTransaction.replace(R.id.frameLHaupt, ldf); fragmentTransaction.commit();
尝试打开 FragmentAddDriver 时,触发了 Declared target fragment that does not belong to this FragmentManager 报错,全程统一使用同一个 getActivity().getSupportFragmentManager(),究竟遗漏了什么关键逻辑?
问题核心成因
该报错和是否统一使用同一个FragmentManager无关,根源出在setTargetFragment()的传参逻辑上:
- 给
FragmentAddDriver设置目标Fragment时,传入的是FragmentHaupt.newInstance("firstP","lastP")创建的全新对象。这个对象没有被任何FragmentManager添加、没有进入Fragment生命周期、也不存在于FragmentManager内部维护的活跃Fragment列表中。 - FragmentManager在校验目标Fragment合法性时,会强制检查传入的target Fragment是否为当前Manager追踪管理的活跃实例。传入的新建实例完全游离于FragmentManager的管理范围之外,自然触发校验失败。
修正方案
- 不要在跳转链路中临时new Fragment实例作为target,从当前Activity的FragmentManager中查找已存在的、被正常管理的
FragmentHaupt实例:在最初添加FragmentHaupt时给它设置固定tag,跳转时通过fragmentManager.findFragmentByTag("预设的HauptFragment标签")拿到真实的活跃实例,再传给setTargetFragment()。 - 明确
setTargetFragment()的设计边界:该API用来绑定两个被同一个FragmentManager管理的活跃Fragment,实现跨Fragment的结果回调,不能传入临时创建的、未被添加到FragmentManager的空Fragment对象。 - 对比
FragmentViewP的target设置逻辑是完全正确的:当时传入的是FragmentHaupt.this,也就是当前真实存在的活跃实例,所以没有触发校验报错。只要把FragmentAddDriver的target参数替换成真实查到的活跃FragmentHaupt实例,即可解决报错。
内容的提问来源于stack exchange,提问作者Nummer Eins
相关产品推荐
相关产品推荐

