Lifecycle/LiveData/ViewModel的使用总结与原理简析
一、Lifecycle
1. 描述
Lifecycle
是一种生命周期感知型组件,可执行操作来响应另一个组件(如 Activity 和 Fragment)的生命周期状态的变化。
这些组件有助于您写出更有条理且往往更精简的代码,这样的代码更易于维护。
2. why?
Lifecycle
的若干重要API:
LifecycleOwner
代表具有生命周期的对象的抽象,诸如Activity、Fragment都是典型的 LifecycleOwner;View的加载(attach)、显示(measure/layout/draw)、卸载(detach)也可以认为具有生命周期,单需要自己提供实现;实质上,任何实现了LifecycleOwner
的对象都可以作为生命周期控制者;Lifecycle
、LifecycleRegistry
:
a. Lifecycle 代表生命周期的抽象,具备关联观察者的方法{@link Lifecycle.addObserver(LifecycleOberver)}
(还有解除关联removeObserver),包含生命周期的状态(State)、事件枚举(Event);
b. LifecycleRegistry 则继承自 Lifecycle, 实现了父类的方法,并且构造时,关联了LifecycleOwner
。结合生命周期拥有者对象的生命周期事件(Event)的分发来确定生命周期的状态(State),进而确定是否通知观察者状态改变。LifecycleObserver
最后状态或数据变化,由观察者接收,进而执行相应的操作。
SO:
由于已知生命周期状态,所以观察者可以根据情况确定执行业务或者终止操作,故而使用这种观察者模式设计的框架具备生周期感知能力。并且,提供了Activity、Fragment默认的实现。
3. 简明使用
举个🌰 : 在 react-native 原生组件中,需要根据原生组件 View 的 “生命周期” 来保证数据的观察、处理和UI的绘制、更新等。
在单 Activity 多 Fragment 的应用中,如果可以获取到 Fragment 的生命周期来做,是最优的方案。当 react-native 的Page在原生端需要知晓 “页面生命周期变化” 无疑是不方便的。
解决方案:
- 使用桥接,将 react-native 的 Page 的 “页面生命周期变化” 告知原生组件;
- 在原生端,根据view 的 attach 、 init、measure、layout、draw、detach来自定生命周期变化。
// 以第二个方案为例
/** 1. 实现LifecycleOwner, 复写{@link LifecycleRegistry.getLifecycle() */
@Supress("ViewCosntructor")
class NativeComponentView(reactContext: ReactContext) : View(reactContext), LifecycleOwner, LifecycleEventListener {
private var registry: LifecycleRegistry = LifecycleRegistry(this@NativeComponentView)
override fun getLifecycle(): Lifecycle = registry
init {
/** 2. 使用ReactContext注册生命周期事件监听 */
reactContext.addLifecycleEventListener(this)
/** 3. 在初始化时分发ON_CREATE事件 */
registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
...
}
...
override fun onAttachedToWindow() {
super.onAttachedToWindow()
/** 3. onAttachedToWindow执行时,视图已经可见,此时分发ON_RESUME事件 */
registry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
/** 4. onDetachedFromWindow执行时,视图已不可见,此时分发ON_PAUSE事件 */
registry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
}
override fun onHostDestroy() {
/** 5. 销毁时,分发ON_DESTROY事件 */
registry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
}
}
不是每个事件都必须有,但是基本的create、resume、pause、destroy必须要有!
在使用LiveData时,如果忘记注册生命周期,将会导致数据观察不生效,observe的onChanged方法不执行的问题!
4. 原理简析
以 androidx.core.app.ComponentActivity
为主线来分析:
- 上图可以了解到,Lifecycle框架是一个典型的
Observable.observe(Observer)
的设计模式(即观察者模式)。其中,Observer是以LifecycleObserver
为父类的一系列生命周期观察者,Observable 是以实现了LifecycleOwner
的子类担当,正如 AppCompatActivity 等等。 androidx.core.app.ComponentActivity
在onCreate
时,调用了Re