Android Java开发:如何从接口回调方法访问Fragment类属性值
问题原因
出现该问题90%以上的场景是回调绑定的Fragment实例和你赋值过lessonsWatched的Fragment实例不是同一个,少数场景是Fragment重建后成员变量没有恢复。
解决方案
方案1(官方推荐,无内存泄漏风险):替换自定义回调为Activity Result API
Android官方已经废弃了startActivityForResult,推荐用该API实现Fragment和Activity的通信,自动绑定当前存活的Fragment实例,不会出现实例不匹配的问题:
- 在Fragment中定义Activity启动器
// 成员变量位置定义 private ActivityResultLauncher<Intent> lessonActivityLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { String lessonId = result.getData().getStringExtra("lesson_id"); // 此处直接访问lessonsWatched即可拿到正确值 Log.d(TAG, "refreshCheckmarks: lessonsWatched: " + lessonsWatched); // 你的刷新逻辑写在这里 } } );
- 替换原跳转逻辑
将你原来跳转Activity的startActivity调用替换为启动器调用:
Intent intent = new Intent(getActivity(), 你的目标Activity类名.class); lessonActivityLauncher.launch(intent);
- 修改目标Activity的关闭逻辑
目标Activity关闭时不要调用自定义回调,直接设置返回结果:
closeBtn.setOnClickListener(v -> { Intent resultIntent = new Intent(); resultIntent.putExtra("lesson_id", 需要回传的id值); setResult(Activity.RESULT_OK, resultIntent); finish(); });
方案2(保留原有自定义回调):修正回调实例绑定逻辑
如果要保留原有接口设计,绝对不要跨组件传递Fragment实例,用静态软引用持有回调:
- 在目标Activity中定义静态回调引用
public class 你的目标Activity类名 extends AppCompatActivity { public static SoftReference<LessonCheckmarkUpdate> sUpdateCallback; // 关闭按钮点击逻辑 closeBtn.setOnClickListener(v -> { if (sUpdateCallback != null && sUpdateCallback.get() != null) { sUpdateCallback.get().refreshCheckmarks(需要回传的id值); } finish(); }); @Override protected void onDestroy() { super.onDestroy(); // 页面销毁时清空引用避免内存泄漏 if (sUpdateCallback != null) { sUpdateCallback.clear(); } } }
- Fragment跳转前绑定回调
在Fragment跳转Activity之前给静态变量赋值为当前Fragment实例:
你的目标Activity类名.sUpdateCallback = new SoftReference<>(this); Intent intent = new Intent(getActivity(), 你的目标Activity类名.class); startActivity(intent);
补充:Fragment重建场景修复
如果是屏幕旋转、系统回收等场景导致Fragment重建,lessonsWatched没有被恢复,需要增加状态保存恢复逻辑:
@Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); if (lessonsWatched != null) { outState.putStringArrayList("lessonsWatched", new ArrayList<>(lessonsWatched)); } } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (savedInstanceState != null) { lessonsWatched = savedInstanceState.getStringArrayList("lessonsWatched"); } // 原有初始化逻辑 }
内容的提问来源于stack exchange,提问作者cesarcarlos
相关产品推荐
相关产品推荐

