我们的在Activity中会比较方便的使用LifeCycle,无论是使用自带实现了LifecycleOwner
的Activity(比如FragmentActivity),还是说单纯的继承Activity
,通过自定义的方式(引入ReportFragment & 实现 LifecycleOwner & 创建 LifecycleRegistry
),他是都能比较方便的通过getLifecycle()
方法拿到Lifecycle
对象的,然后我们的ViewModel的LiveData
就可以关联上Activity的生命周期,也可以较为方便的添加/删除LifecycleObserver
对象。
但是我们在Fragment中,就会有一些疑惑,比如我们的Fragment他是有提供两种方式去获取Lifecycle
对象,
1 | mModel.liveData.observe(this){ |
例如上面提供的两个例子,第一种情况是我们的Fragment它是实现了LifecycleOwner
,通过通过getLifecycle()
是能观测到Fragment的生命周期变化的。第二种则是通过getViewLifecycleOwner()
的方式来拿到一个LifecycleOwner
对象,他也是能观测到Fragment的生命周期变化的。
然后Fragment中实现getLifecycle()
的方式与Activity的方式是不一样的,后者是通过Fragment实现,前者是直接调用LifecycleRegistry
实现:
1 | //在Fragment的对应的生命周期中,LifecycleRegistry会调用对应的生命周期回调 |
然后getViewLifecycleOwner()
,他是基于FragmentViewLifecycleOwner
:
1 | onActivityCreated() -> handleLifecycleEvent(Lifecycle.Event.ON_CREATE) // 前者先执行,该回调不一定执行,只有在restore的情况下,Fragment被重建了才会执行 |
通过上面的回调我们就可以看到getLifecycle()
与getViewLifecycleOwner()
的不同。
然后我们看一个例子来自Jetpack MVVM 七宗罪之一:使用 Fragment 作 LifecycleOwner:
1 | val handler = Handler(Looper.getMainLooper()) |
在点击按钮之后,点击返回键可以发现数据打印了两次,因为我们的Fragment假如是通过addToBackStack
的方式,MyFragment1
被替换的时候,不会走到onDestroy()
,而是走到了onDestroyView()
。点击返回键的时候,需要重新去走onViewCreated
,就导致了我们会创建两个Observer
,就会打印两次。
假如是使用getViewLifecycleOwner()
,则会正常的打印一次,LiveData在onDestroyView()
触发下面的方法,移除掉首次添加的Observer
对象。
1 | // LiveData |
所以,我们在Fragment中,最好还是使用getViewLifecycleOwner()
去做UI的战士,因为它是跟随了Fragment的View的状态变化以及生命周期的。