onDestroyView()之后调用了onSaveInstanceState()片段



由于Fragment的一些生命周期问题,应用程序开始收到一些崩溃(不能100%再现(。

我正在使用视图绑定,并根据Android建议手动使绑定无效,以避免在Fragment销毁后保留对绑定的引用时占用大量内存。

private var _binding: FragmentCustomBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View = FragmentCustomBinding.inflate(inflater, container, false).also {
_binding = it
}.root
override fun onDestroyView() {
_binding = null
super.onDestroyView()
}
override fun onSaveInstanceState(outState: Bundle) {
outState.apply {
putString(BUNDLE_KEY_SOME_VALUE, binding.etSomeValue.text.toString())
}
super.onSaveInstanceState(outState)
}

我在onSaveInstanceState()中得到一个NullPointerException,因为bindingnull,因为它是在onDestroyView()之后调用的。

你知道我如何在不手动创建保存状态并手动处理的情况下解决这个问题吗?

binding = null导致了此问题。要以正确的方式消除_binding=null,请使用以下代码:

class CustomFragment : Fragment(R.layout.fragment_custom) {
private val binding: FragmentCustomBinding by viewBinding()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Any code we used to do in onCreateView can go here instead
}
}

根据一篇关于这种变通方法的文章:

此技术使用可选的backing字段和非可选的val,该字段仅在onCreateView和onDestroyView之间有效。在onCreateView中,会设置可选的backing字段,而在onDestroyView中,则会清除该字段。这修复了内存泄漏!

这似乎取决于如何处理片段,即使它们没有视图,因为"活动"状态的更改仍然可以触发onSavedInstanceState(),因此我可能会出现处于onSavedInstanceState()但没有视图的情况。这似乎是有意的,因为无论碎片是否有观点,它们都仍然得到支持。

建议使用视图API来保存和恢复状态(或我的SavedStateRegistery(。

可以在此处找到更多详细信息:https://issuetracker.google.com/issues/245355409

最新更新