:当 getView() 为空时,即在 onCreateView() 之前或 onDestroyView() 之后,无法访问 Fragment View 的 LifecycleOwner

问题描述 投票:0回答:13

我在我的应用程序中使用实时数据进行所有网络调用和响应处理。

在其中一个场景中,我的回收者视图正在其视图持有者的

onBind
中加载一些数据,并且响应正在更新 UI。为此,我必须向观察者提供
lifecycleOwner

由于回收者视图没有自己的任何生命周期所有者,因此我通过使用

parentFragment.viewlifecycleOwner
为此使用了父片段,但不知何故它给出了一个错误。

当父片段没有实例时,视图持有者如何拥有实例?

viewModel.responseState.observe(parentFragment.viewLifecycleOwner, Observer {
    updateUI(it)
})

致命异常:java.lang.IllegalStateException:当 getView() 为空时无法访问片段视图的 LifecycleOwner,即在 onCreateView() 之前或 onDestroyView() 之后

android android-recyclerview android-lifecycle
13个回答
13
投票

这可以通过触发引发错误的逻辑来解决,从

onCreateView(...)
回调结束左右(不是
onCreate(...)
也不是
onAttach(...)
)。

getViewLifecycleOwner() 文档中,我不认为,我可以解释得更好:

第一个可以安全访问视图生命周期的方法是onCreateView(LayoutInflater, ViewGroup, Bundle),条件是必须返回一个非空视图(如果访问视图生命周期但不返回会抛出IllegalStateException)返回一个非空视图)。

视图生命周期通过调用onDestroyView()保持有效,之后getView()将返回null,视图生命周期将被销毁,该方法将抛出IllegalStateException。考虑使用 getViewLifecycleOwnerLiveData() 或 FragmentTransaction.runOnCommit(Runnable) 在 Fragment 的视图生命周期可用时接收回调。

public LifecycleOwner getViewLifecycleOwner() {
    if (mViewLifecycleOwner == null) {
        throw new IllegalStateException("Can't access the Fragment View's LifecycleOwner when "
                + "getView() is null i.e., before onCreateView() or after onDestroyView()");
    }
    return mViewLifecycleOwner;
}

8
投票

我遇到了同样的问题,我可以用下面的代码修复它,只需检查视图是否为空

     if ( view != null)
       viewModel.responseState.observe(parentFragment.viewLifecycleOwner, Observer {
       updateUI(it) })

4
投票

我的解决方案是在 onViewCreated 中编写代码而不是在 onCreateView 中编写.... 我的问题解决了。


1
投票

问题是即使在视图被销毁后(当您导航到下一个片段时),观察者仍然在父母的

viewLifecycleOwner
上处于活动状态。解决这个问题最可靠的方法是清除观察者。

override fun onDestroyView()
    viewModel.responseState.removeObservers(parentFragment.viewLifecycleOwner)
    super.onDestroyView()
}

0
投票

我的解决方案被简化了。我正在使用单独的观察者 - 一个用于从主要活动(或仅从任何活动)使用 Lifecycleowner 的网络,另一个用于片段视图(模型视图视图模型)。


0
投票
 myModel.getOfflineData().observeForever(new Observer<List<indiaStateModel>>() {
                @Override
                public void onChanged(List<indiaStateModel> indiaStateModels) {
                    adapter = new stateAdapter(indiaStateModels);
                    recyclerView.setAdapter(adapter);
                }
            });

// 当你得到那个错误时使用这个永远的观察者 // 主要是当您尝试将手机主题从深色变为浅色时出现此错误 或从浅到深


0
投票

最好使用 FLow() 而不是 LiveData()

将 LiveData() 转换为 Flow()

之前

viewModel.responseState.observe(parentFragment.viewLifecycleOwner, Observer {
    updateUI(it)
})

之后

lifecycleScope.launch {

viewModel.responseState.asFlow().collectLatest{
 
updateUI(it)

l̥

}

}

0
投票

在我的例子中,我将观察者设置为可运行的视图:

view.post(() ->{
    ...
    viewModel.getDate().observe();
})

0
投票

我按照 android studio viewLifecycleOwnerLiveData 的建议使用。 所以你的情况会像

    parentFragment.viewLifecycleOwnerLiveData.value?.let { nonNullViewLifecycleOwner -> 
       viewModel.responseState.observe(nonNullViewLifecycleOwner, Observer   {
          updateUI(it)
       })
    }

希望对您有所帮助!


0
投票

在 onViewCreated 函数中观察视图模型实时数据。或者你可以检查this out


0
投票

我通过确保我在片段的 onDestroyView() 中清除所有订阅而不是在 onDestroy() 中来解决这个问题。 这完全修复了它! 在调用 onDestroyView() 后,我的代码试图访问视图。


-2
投票

正如您的评论,解决方案是确保片段的视图不为空。这发生在我身上,ViewPager 中有一个片段。


-3
投票
override fun onDestroyView()
    viewModel.responseState.removeObservers(parentFragment.viewLifecycleOwner)
    super.onDestroyView()
}

Check if there view is Destroy then Lifecycle Owner cant perform of updating UI so it is getting crash

so stop the action if on View has Destroy
© www.soinside.com 2019 - 2024. All rights reserved.