Fragment
应用基础 · androidx.fragment
Fragment 事务与 Back Stack1.9.0-rc01
commit、commitNow、addToBackStack 和 state loss 的实际边界。
最后更新 2026-08-01
基本事务
supportFragmentManager.commit {
setReorderingAllowed(true)
replace<DetailFragment>(R.id.container, args = args)
addToBackStack("detail")
}| API | 行为 |
|---|---|
commit() | 异步排队到主线程执行(默认) |
commitNow() | 同步立即执行;不能与 addToBackStack 同用 |
commitAllowingStateLoss() | 状态已保存后仍允许提交(有风险) |
commitNowAllowingStateLoss() | 同步 + 允许状态丢失 |
普通页面切换优先异步 commit——让 FragmentManager 按正常队列和生命周期完成操作。
addToBackStack:可返回
supportFragmentManager.commit {
replace<A>(R.id.container)
addToBackStack("a") // 记录:返回时回到之前状态
}
// 返回
supportFragmentManager.popBackStack()
// 按 name 弹出
supportFragmentManager.popBackStack("detail", PopBackStackFlags.INCLUSIVE)addToBackStack(name)把当前事务状态压入返回栈。- 返回时逆序回放事务(旧 Fragment 恢复而不是重建)。
setReorderingAllowed(true)允许优化中间状态,back stack 事务获得正确生命周期/动画。
state loss:为什么不要乱用 AllowingStateLoss
// ❌ 危险:onSaveInstanceState 之后 commit,进程恢复时可能丢
if (savedInstanceState == null) {
supportFragmentManager.commitAllowingStateLoss { ... }
}commitAllowingStateLoss 允许在状态已保存后提交,但该变化可能在进程恢复时消失。它不是解决生命周期错误的通用方案——正确做法是把导航事件放回可提交的生命周期窗口(onCreate 之后、状态保存之前)。
事务的三种操作
supportFragmentManager.commit {
add<A>(R.id.container) // 添加(不销毁现有)
remove(existingFragment) // 移除
replace<B>(R.id.container) // 移除旧 + 添加新
hide(fragment) / show(fragment) // 隐藏/显示(保留状态)
}hide/show 保留 Fragment 状态(适合 tab);replace 销毁旧实例(回收内存)。
常见陷阱
- commitNow + addToBackStack:IllegalStateException。
- 状态保存后 commit:IllegalStateException 或状态丢失。
- replace 后 View 状态丢失:替换会销毁旧 Fragment。
- 忘 setReorderingAllowed:动画/生命周期异常(新版本默认 false)。
- Fragment 引用泄漏:事务后仍持有旧 Fragment 引用。
复制即用
class MainFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.openDetail.setOnClickListener {
parentFragmentManager.commit {
setReorderingAllowed(true)
replace<DetailFragment>(
R.id.fragment_container,
args = Bundle().apply { putString("id", itemId) },
)
addToBackStack("detail")
}
}
}
}要点
- 异步
commit是默认;commitNow同步但不能进返回栈。 addToBackStack让事务可返回;返回栈逆序回放。- 状态保存后提交用 AllowingStateLoss 但有丢失风险——把导航放回正确窗口。
hide/show保状态,replace换实例。