换一种描述方式:LiveData 缓存了最新的数据并将其传递给正活跃的组件。
关于数据驱动的详解可以点击我是怎么把业务代码越写越复杂的 | MVP - MVVM - Clean Architecture。
这一篇就 LiveData 的面试题做一个归总、分析、解答。
1. LiveData 如何感知生命周期的变化?
先总结,再分析:
- Jetpack 引入了 Lifecycle,让任何组件都能方便地感知界面生命周期的变化。只需实现 LifecycleEventObserver 接口并注册给生命周期对象即可。
- LiveData 的数据观察者在内部被包装成另一个对象(实现了 LifecycleEventObserver 接口),它同时具备了数据观察能力和生命周期观察能力。
常规的观察者模式中,只要被观察者发生变化,就会无条件地通知所有观察者。比如java.util.Observable
:
public class Observable {
private boolean changed = false;
private Vector<Observer> obs;
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
if (!hasChanged())
return;
arrLocal = obs.toArray();
clearChanged();
}
// 无条件地遍历所有观察者并通知
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
}
// 观察者
public interface Observer {
void update(Observable o, Object arg);
}
复制代码
LiveData 在常规的观察者模式上附加了条件,若生命周期未达标,即使数据发生变化也不通知观察者。这是如何实现的?
生命周期
生命周期是一个对象从构建到消亡过程中的各个状态的统称。
比如 Activity 的生命周期用如下函数依次表达:
onCreate()
onStart()
onResume()
onPause()
onStop()
onDestroy()
复制代码
要观察生命周期就不得不继承 Activity 重写这些方法,想把生命周期的变化分发给其他组件就很麻烦。
于是 Jetpack 引入了 Lifecycle,以让任何组件都可方便地感知生命周期的变化:
public abstract class Lifecycle {AtomicReference<>();
// 添加生命周期观察者
public abstract void addObserver(LifecycleObserver observer);
// 移除生命周期观察者
public abstract void removeObserver(LifecycleObserver observer);
// 获取当前生命周期状态
public abstract State getCurrentState();
// 生命周期事件
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY;
}
// 生命周期状态
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
}
// 判断至少到达了某生命周期状态
public boolean isAtLeast(State state) {
return compareTo(state) >= 0;
}
}
复制代码
Lifecycle 即是生命周期对应的类,提供了添加/移除生命周期观察者的方法,在其内部还定义了全部生命周期的状态及对应事件。
生命周期状态是有先后次序的,分别对应着由小到大的 int 值。