从Fragment2按返回键回到Fragment1时onCreate未执行如何解决
问题原因
这个现象是安卓Fragment的标准生命周期逻辑:
你调用addToBackStack()执行replace跳转Fragment2时,Fragment1的实例不会被销毁,仅会销毁它的视图结构。当你按返回键回退时,系统会复用已存在的Fragment1实例重建视图,所以只会触发onCreateView()及之后的生命周期方法,onCreate()仅会在Fragment实例第一次被创建时执行一次,自然不会被调用。
解决方案
方案1:调整代码执行的生命周期位置(推荐)
这是最符合安卓设计规范的实现方式,无需改动原有跳转逻辑:
- 如果你的代码和视图初始化、绑定相关,直接把
onCreate()中的对应代码迁移到onCreateView()或者onViewCreated()中即可,这两个方法每次回退重建视图时都会触发 - 如果你的代码和视图无关,仅需要Fragment每次回到前台可见时执行,可以把代码迁移到
onResume()方法中
方案2:禁用回退栈,回退时手动创建新的Fragment1实例
如果业务逻辑必须要求onCreate()执行,可以放弃系统回退栈能力,自己实现回退逻辑:
- 首先修改Fragment1跳转Fragment2的代码,去掉
addToBackStack()调用:
getParentFragmentManager().beginTransaction() .replace(R.id.host_fragment, new Fragment2()) .commit();
- 在承载Fragment的宿主Activity中重写
onBackPressed()方法:
@Override public void onBackPressed() { Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.host_fragment); // 当前在Fragment2页面时,手动创建新的Fragment1实例替换,会触发完整onCreate流程 if (currentFragment instanceof Fragment2) { getSupportFragmentManager().beginTransaction() .replace(R.id.host_fragment, new Fragment1()) .commit(); return; } super.onBackPressed(); }
方案3:保留回退栈,回退时先销毁旧的Fragment1实例
如果需要保留其他页面的回退栈逻辑,可以在回退到Fragment1前手动销毁旧实例,让系统重建新实例:
- 初始加载Fragment1时给实例加Tag标记:
getSupportFragmentManager().beginTransaction() .replace(R.id.host_fragment, new Fragment1(), "f1") .commit();
- 跳转Fragment2时给回退栈加名称标记:
getParentFragmentManager().beginTransaction() .addToBackStack("jump_to_f2") .replace(R.id.host_fragment, new Fragment2()) .commit();
- 宿主Activity重写
onBackPressed()方法:
@Override public void onBackPressed() { if (getSupportFragmentManager().getBackStackEntryCount() > 0) { BackStackEntry topEntry = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1); // 判断当前要回退的是从Fragment2回到Fragment1的场景 if ("jump_to_f2".equals(topEntry.getName())) { Fragment oldF1 = getSupportFragmentManager().findFragmentByTag("f1"); if (oldF1 != null) { // 先移除旧的Fragment1实例 getSupportFragmentManager().beginTransaction().remove(oldF1).commitNow(); } } } super.onBackPressed(); }
注意事项
onCreate()的设计初衷就是仅在Fragment实例第一次创建时执行一次的初始化逻辑,除非有特殊的强需求,非常不推荐强制让它重复执行,可能会导致变量重复初始化、内存泄漏、逻辑异常等问题,优先选择方案1调整代码位置是成本最低、稳定性最高的实现方式。
内容的提问来源于stack exchange,提问作者Hamed
相关产品推荐
相关产品推荐

