Android API33下setTargetFragment/getTargetFragment废弃替代方案
替换方案说明
API 33 中setTargetFragment()、getTargetFragment()被正式废弃,原有机制存在状态恢复时引用泄漏、实例不一致的问题,官方推荐使用Fragment Result API实现同栈Fragment间的数据回传,可1:1替代原有手动调用onActivityResult的逻辑,稳定性更强。
具体实现步骤
- 第一步:在发起跳转的源Fragment(即你代码中的
AddMedia)中注册结果回调,替代原有getTargetFragment()类型校验、结果接收逻辑。注意回调需要在onCreate生命周期注册,保证配置变更、进程重建后仍能正常收到结果:
public class AddMedia extends Fragment { // 定义统一的结果key和请求码,和原有逻辑对齐 public static final String GALLERY_RESULT_KEY = "media_gallery_result"; public static final int REQ_CODE_GALLERY = 104; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 注册结果监听 getParentFragmentManager().setFragmentResultListener(GALLERY_RESULT_KEY, this, (requestKey, result) -> { int requestCode = result.getInt("requestCode", -1); int resultCode = result.getInt("resultCode", Activity.RESULT_CANCELED); Intent returnData = result.getParcelable("data"); // 原有onActivityResult中的业务逻辑直接迁移到这里 if (requestCode == REQ_CODE_GALLERY && resultCode == Activity.RESULT_OK) { // 处理Media_Gallery回传的数据 } }); } // 其余原有代码不变 }
- 第二步:修改Fragment启动逻辑,删除
setTargetFragment()调用,其余事务逻辑保持不变:
Media_Gallery gallery = new Media_Gallery(); // 删除原有 gallery.setTargetFragment(AddMedia.this,104); 代码 FragmentTransaction fragmentTrasaction = getParentFragmentManager().beginTransaction(); fragmentTrasaction.addToBackStack("Image"); fragmentTrasaction.replace(R.id.Main_Layout, gallery, "Image"); fragmentTrasaction.commit();
- 第三步:修改被启动的
Media_Gallery中的回传逻辑,删除原有getTargetFragment()类型判断、手动调用onActivityResult的代码,替换为Fragment Result API投递结果:
// 在需要回传数据的位置(比如资源选择完成、返回按钮点击事件中)执行 Intent returnIntent = new Intent(); // 按原有逻辑塞入需要回传的参数 Bundle resultBundle = new Bundle(); resultBundle.putInt("requestCode", AddMedia.REQ_CODE_GALLERY); resultBundle.putInt("resultCode", Activity.RESULT_OK); resultBundle.putParcelable("data", returnIntent); // 投递结果 getParentFragmentManager().setFragmentResult(AddMedia.GALLERY_RESULT_KEY, resultBundle); // 正常关闭当前Fragment即可 getParentFragmentManager().popBackStack();
注意事项
- 注册监听和投递结果必须使用同一个FragmentManager,你原有代码使用的是
getParentFragmentManager(),两边保持一致即可,不要混用getChildFragmentManager()或getSupportFragmentManager(),否则会出现收不到结果的问题。 - 原有
if (getTargetFragment() instanceof FragmentA)的校验逻辑可以完全删除,Fragment Result按自定义的唯一key定向投递,只有注册了对应key的Fragment能收到结果,不会出现错发问题。 - 这套实现兼容AndroidX Fragment 1.3.0及以上版本,覆盖绝大多数现有项目的依赖配置,不需要额外引入新依赖,同时天然支持页面重建后的结果恢复,不会出现原有targetFragment机制下的空指针、实例错位问题。
内容的提问来源于stack exchange,提问作者Ritu
相关产品推荐
相关产品推荐

