Android 使用视图绑定和实时数据观察程序在片段中崩溃

Android 使用视图绑定和实时数据观察程序在片段中崩溃,android,android-fragments,android-lifecycle,android-livedata,android-viewbinding,Android,Android Fragments,Android Lifecycle,Android Livedata,Android Viewbinding,这是我的实现: class SampleFragment : Fragment() { private val viewModel by sharedViewModel<MyViewModel>() override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = FragmentSam

这是我的实现:

class SampleFragment : Fragment()
{
    private val viewModel by sharedViewModel<MyViewModel>()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
            FragmentSampleBinding.inflate(inflater, container, false).apply {
                myButton.setOnClickListener { viewModel.foo() }

                viewModel.statusLiveData.observe(viewLifecycleOwner, Observer {
                    titleTextView.text = it.status.title
                    myButton.text = it.status.button_title
                })
            }.root
}
一种想法是,当视图在
observe()
订阅结束之前被销毁时,就会发生这种情况

我深入研究了片段代码,在FragmentManager中发现了以下内容:

private void destroyFragmentView(@NonNull Fragment fragment) {
    fragment.performDestroyView();
    mLifecycleCallbacksDispatcher.dispatchOnFragmentViewDestroyed(fragment, false);
    fragment.mContainer = null;
    fragment.mView = null;
    // Set here to ensure that Observers are called after
    // the Fragment's view is set to null
    fragment.mViewLifecycleOwner = null;
    fragment.mViewLifecycleOwnerLiveData.setValue(null);
    fragment.mInLayout = false;
}
viewLifecycleOwner
实际上是在视图销毁后销毁的。但是由于这个函数是不可挂起的,所以不应该有从主线程交错的方法

我的假设正确吗

我进一步发现,如果存在退出转换(FragmentManager#moveToState()第1261+行):

然而,这也会延迟视图的销毁

你知道坠机是怎么发生的吗?
(我在样本中留下了
sharedViewModel
的Koin注入,以防这可能是问题的根源。)

将观察员注册代码移动到
onViewCreated
。我认为问题在于,如果您的livedata已经准备好了一个值,它会立即触发观测者,该观测者尝试访问该视图,但它无法成功,因为
onCreateView
尚未返回fragments视图。那么,实际为空的是什么?是不是
it
it.status
?因为
titleTextView
myButton
,假设它们是您膨胀的绑定的一部分,不能为null。@Pawel我知道这是使用kotlinx synthetic时的要求。当使用视图绑定时,我可以在根视图设置为根视图之前通过绑定访问根视图,对吗?您是否有在
onViewCreated()
中注册的源代码?@ianhanniballake是,
titleTextView
myButton
是绑定的一部分。不幸的是,我无法重现崩溃,堆栈跟踪就是我所有的信息。听起来你需要查看
statusLiveData
,以及在
LiveData
上设置值的每个地方。您尚未包含该代码,因此我们无法帮助检查
it
it.status
是否为空。
private void destroyFragmentView(@NonNull Fragment fragment) {
    fragment.performDestroyView();
    mLifecycleCallbacksDispatcher.dispatchOnFragmentViewDestroyed(fragment, false);
    fragment.mContainer = null;
    fragment.mView = null;
    // Set here to ensure that Observers are called after
    // the Fragment's view is set to null
    fragment.mViewLifecycleOwner = null;
    fragment.mViewLifecycleOwnerLiveData.setValue(null);
    fragment.mInLayout = false;
}
// If a fragment has an exit animation (or transition), do not destroy
// its view immediately and set the state after animating
if (mExitAnimationCancellationSignals.get(f) == null) {
    destroyFragmentView(f);
} else {
    f.setStateAfterAnimating(newState);
}