我在我的应用程序中使用实时数据进行所有网络调用和响应处理。
在其中一个场景中,我的回收者视图正在其视图持有者的
onBind
中加载一些数据,并且响应正在更新 UI。为此,我必须向观察者提供lifecycleOwner
。
由于回收者视图没有自己的任何生命周期所有者,因此我通过使用
parentFragment.viewlifecycleOwner
为此使用了父片段,但不知何故它给出了一个错误。
当父片段没有实例时,视图持有者如何拥有实例?
viewModel.responseState.observe(parentFragment.viewLifecycleOwner, Observer {
updateUI(it)
})
致命异常:java.lang.IllegalStateException:当 getView() 为空时无法访问片段视图的 LifecycleOwner,即在 onCreateView() 之前或 onDestroyView() 之后
这可以通过触发引发错误的逻辑来解决,从
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;
}
我遇到了同样的问题,我可以用下面的代码修复它,只需检查视图是否为空
if ( view != null)
viewModel.responseState.observe(parentFragment.viewLifecycleOwner, Observer {
updateUI(it) })
我的解决方案是在 onViewCreated 中编写代码而不是在 onCreateView 中编写.... 我的问题解决了。
问题是即使在视图被销毁后(当您导航到下一个片段时),观察者仍然在父母的
viewLifecycleOwner
上处于活动状态。解决这个问题最可靠的方法是清除观察者。
override fun onDestroyView()
viewModel.responseState.removeObservers(parentFragment.viewLifecycleOwner)
super.onDestroyView()
}
我的解决方案被简化了。我正在使用单独的观察者 - 一个用于从主要活动(或仅从任何活动)使用 Lifecycleowner 的网络,另一个用于片段视图(模型视图视图模型)。
myModel.getOfflineData().observeForever(new Observer<List<indiaStateModel>>() {
@Override
public void onChanged(List<indiaStateModel> indiaStateModels) {
adapter = new stateAdapter(indiaStateModels);
recyclerView.setAdapter(adapter);
}
});
// 当你得到那个错误时使用这个永远的观察者 // 主要是当您尝试将手机主题从深色变为浅色时出现此错误 或从浅到深
最好使用 FLow() 而不是 LiveData()
将 LiveData() 转换为 Flow()
之前
viewModel.responseState.observe(parentFragment.viewLifecycleOwner, Observer {
updateUI(it)
})
之后
lifecycleScope.launch {
viewModel.responseState.asFlow().collectLatest{
updateUI(it)
l̥
}
}
在我的例子中,我将观察者设置为可运行的视图:
view.post(() ->{
...
viewModel.getDate().observe();
})
我按照 android studio viewLifecycleOwnerLiveData 的建议使用。 所以你的情况会像
parentFragment.viewLifecycleOwnerLiveData.value?.let { nonNullViewLifecycleOwner ->
viewModel.responseState.observe(nonNullViewLifecycleOwner, Observer {
updateUI(it)
})
}
希望对您有所帮助!
在 onViewCreated 函数中观察视图模型实时数据。或者你可以检查this out
我通过确保我在片段的 onDestroyView() 中清除所有订阅而不是在 onDestroy() 中来解决这个问题。 这完全修复了它! 在调用 onDestroyView() 后,我的代码试图访问视图。
正如您的评论,解决方案是确保片段的视图不为空。这发生在我身上,ViewPager 中有一个片段。
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