Androidx Fragments中的getViewLifeCycleOwner()与'this'与this.getActivity()之间的区别

22
我们在fragment中经常使用LiveData的observe方法。最近发布的androidx fragment sdk版本导致Android Studio将liveDataObject.observe(this)的实例标记为错误,建议使用liveDataObject.observe(getViewLifecycleOwner())
引入了一个新的Lint检查,确保您在onCreateView()、onViewCreated()或onActivityCreated()中观察LiveData时使用getViewLifecycleOwner()。(b/137122478)https://developer.android.com/jetpack/androidx/releases/fragment 我们担心实现这个更改,因为我们不理解getViewLifecycleOwner()的功能与使用this相比有何区别,以及当在fragment中设置ViewModel时是否会与使用thisthis.getActivity()发生冲突。
此外,我们使用Android Navigation组件,并注意到当用户在同一activity中导航到不同的fragment时,每个fragment的onDestroyView()方法被调用,但不包括onDestroy()
以下是我们在onViewCreated()中的代码示例。
 vm.getStemLengths().observe(this, stemLengths -> {
        this.stemLengths = new ArrayList<>(Stream.of(stemLengths).map(stemLength ->
                new SearchModel(Integer.toString(stemLength.getValue()))).toList());
  });

稍后,在onDestroyView()

 vm.getStemLengths().removeObservers(this);

同时,根据片段的不同,包含LiveData的ViewModel将设置以下之一:

 vm = new ViewModelProvider(this.getActivity()).get(PrepareVM.class);

为了在活动的多个片段之间保持viewmodel的持久性。
或者:
vm = new ViewModelProvider(this).get(AprobacionVM.class);

如果虚拟机不需要在当前片段之外持久存在,则可以不需要持久化。总结一下,当在片段的onCreateView()中观察LiveData对象时,将this更改为getViewLifeCycleOwner()是否会与ViewModel模式/导航组件冲突?例如,可能会出现LiveData更改会触发来自同一活动中先前片段的观察者的实例,用户从该实例中导航离开。从getViewLifeCycleOwner的文档中可以看出,进行此更改可能允许我们在每个片段的onDestroyView()中删除removeObservers()调用。这是正确的理解吗?
2个回答

20

Fragment 实现了 LifecycleOwner 接口,将其创建和销毁事件映射到片段的 onCreateonDestroy 方法上。

Fragment.getViewLifecycleOwner() 将其创建和销毁事件映射到片段的 onViewCreatedonDestroyView 方法上。具体的顺序请参见这里

如果您在观察者中使用视图,您需要使用视图生命周期。否则,当视图层次结构无效时,您可能会收到更新通知,这可能导致崩溃。

从 getViewLifeCycleOwner 的文档中看来,进行此更改可能允许我们在每个片段的 onDestroyView() 中删除 removeObservers() 调用。

正确。


感谢您的回复!一方面,在onDestroyView()中调用removeObservers()不再需要,但另一方面,getViewLifecycleOwner()使用了片段的onDestroy()方法。因此,如果onDestroy()方法没有被调用(就像我们的情况一样,当用户导航离开时只调用onDestroyView()),那么LiveData观察者将不会被移除,对吗? - user1114
onDestroyView,这是我犯的一个相当糟糕的打字错误,非常抱歉。视图生命周期确实以 onDestroyView 结束。 - Eugen Pechanec

0

它已经有一个错误了。如果您为已经使用的片段创建新的Intent,则会出现getView为空的错误。为什么?该活动是新创建的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接