如果我们用过Rxjava 的话知道,Rxjava 是基于观察者模式实现的异步数据处理库,它可以在我们订阅的时候向我们分发数据,但有一点可惜的是Rxjava 的Observable 并不具备组件生命周期感知的能力,所以当我们在一个组件生命周期即将结束时取消订阅和数据分发时,需要手动去取消订阅;而谷歌官方退出的LiveData 恰恰解决了这个问题,LiveData 是一个数据持有者,同时它又具备了组件生命周期感知能力。当LiveData观察者处于非Active 状态时,LiveData不会将最新的变化通知给观察者。通常LiveData可以搭配ViewModel 一起使用,ViewModle 作为LiveData 的数据源,当数据更新后,LiveData会通知它的观察者。
LiveData 一般搭配ViewModel 使用,使用方式如下:
class MyViewModel: ViewModel() {
#1 声明LiveData
val mutableLiveData = MutableLiveData()
}
lass MainActivity : AppCompatActivity() {
private lateinit var myViewModel: MyViewModel
private lateinit var tv:TextView
private lateinit var btnSetValue:Button
private lateinit var btnPostValue:Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
#2 初始化ViewModel
myViewModel= ViewModelProvider(this@MainActivity)[MyViewModel::class.java]
tv = findViewById(R.id.tv1)
btnSetValue = findViewById(R.id.btn_set_value)
btnPostValue = findViewById(R.id.btn_post_value)
#3 LiveData注册监听事件
myViewModel.mutableLiveData.observe(this@MainActivity){
tv.text= it
}
#4 调用LiveData setValue
btnSetValue.setOnClickListener {
myViewModel.mutableLiveData.value="this is value from set"
}
#5 调用LiveData postValue
btnPostValue.setOnClickListener {
thread {
myViewModel.mutableLiveData.postValue("this is value from post")
}
}
}
#1.首先在ViewModel 中声明LiveData 变量,其中泛型决定了LiveData中持有数据的类型。
#2.在Activity 中 初始化ViewModel 对象。
#3. 给ViewModel 中的LiveData变量注册监听事件,当LiveData 的值发生变化时我们将值显示在TextView 上。
#4. 调用LiveData 的setValue ()方法,改变持有的数据值,并通知上面注册的观察者, 这个方法必须要在主线程中调用,否则会抛出异常。
#5. 调用LiveData 的 postValue() 方法,改变持有的数据值,并通知上面注册的观察者, 这个方法既可以在主线程调用也可以在子线程中调用。
上面的图示分别表示执行#4 #5 后的效果。
这里先从LiveData 的observer()方法开始:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
#1 必须在主线程注册
assertMainThread("observe");
#2 这里查看LifecyclerOwner 的状态,如果是销毁状态,则返回
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
#3 将LifecycleOwner 和监听事件 封装为LifecycleBoundObserver 对象
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
#4 LifecycleBoundObserver 对象存在SafeIterableMap中
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
#5 同一个监听事件不能绑定在不同的LifecycleOwner 上
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
#6 将上面的wrapper 作为观察者添加到LifecycleOwner维护的观察者列表中,以此来绑定
LifecyclOwner的生命周期
owner.getLifecycle().addObserver(wrapper);
}
这里需要涉及到Lifecycle的一些知识,如果 不了解Lifecyle 可以自行了解下Lifecycle.
#1. 主线程校验, LiveData注册监听事件必须在主线程中。
#2.如果当前所在的LifecycleOwner 也就是Activity 或者Fragment 已被销毁,则返回
#3. 将LifecycleOwner 和监听对象Observer 封装为LifecycleBoundObserver 对象, LifecycleBouondObserver 继承了ObserverWrapper 类并且实现了LifecycleEventObserver,所以它本质上是一个LifecycleOwner 生命周期的观察者, 当Activity 或者Fragment 生命周期发生变化时,会调用其内部重写的onStateChanged() 方法,改变其内部维护的Active 状态(可见为true, 不可见为false);当LiveData 的值发生变化时,会根据Active 状态决定是否下发改变的值。
#4 将LifecycleBoundObserver对象保存在观察者列表中
#5 同一个监听对象只能绑定在一个LifecycleOwner 上
#6 将LifecycleBoundObserver 对象添加到LifecycleOwner 维护的观察者列表中
总结一下:这个方法主要是将LiveData 监听对象Observer以及其所在的生命周期所有者LifecycleOwner(Activity 或者Fragment) 封装成LifecycleBoundObserver 对象并添加到 LiveData 维护的观察者列表中,随后将LifecycleBoundObserver 对象作为观察者注册到LifecycleOwner 维护的观察者列表中,这样当LifeycleOwner 也就是Activity 或者Fragment 生命周期发生变化时,LifecycleBoundObserver 的Active状态也会发生变化,当LiveData 的值发生改变时,会根据监听对象LifecycleBoundObserver所在的LifecycleOwner 的Active 状态是否活跃来确定是否要下发改变的值。
接着我们来看一下LifecycleBoundObserver 类
#1 LiveData 的内部类,继承ObserverWrapper实现了LifecycleEventObserver, 所以他是Lifecyle 中的一个观察者
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
#2 Activity、Fragment 或者自定义的具有生命的对象
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
#3 LifecycleEventObserver 接口中的方法,LifecycleOwner 生命周期变化时调用
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
#4 获取LifecycleOwner 的状态
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
#5 如果LifecycleOwner处于销毁状态,移除监听事件
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
#6 改变状态并决定是否分发事件
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
#7 ObserverWrapper 中的方法,为了方便我挪了出来
void activeStateChanged(boolean newActive) {
#8 活跃状态没有变化,返回
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
#9 处于活跃状态,下发值
if (mActive) {
dispatchingValue(this);
}
}
}
这里主要看的是#3 当LifecycleOwner 生命周期发生变化时,调用onStateChanged() 方法,如果当前LifecycleOwner 状态是销毁状态,则移除监听事件;如果没有销毁,调用activeStateChanged() 方法来改变活跃状态,只有当LifecycleOwner 的状态至少是State.STARTED 时,mActive 为true 否则mActive 为false;如果新的状态同上次的状态相同,则什么都不做,如果不同,则判断当前状态mActive是否活跃,如果为true 则调用LiveData 的dispatchingValue()方法来下发值。
这块可能有点绕,如果了解Lifecycle 的状态就会好理解很多,Lifecycle中维护着生命周期的事件Event和状态State两个枚举,当某个生命周期事件执行完毕后,那么Lifecycle 就处于某个特定的状态State, 其对应关系如下:
Event --------------------------> State
ON_CREATE
ON_STOP CREATED
ON_START
ON_PAUSE STARTED
ON_RESUME RESUMED
ON_DESTRORY DESTROYED
可以看到当LifecycleOwner 状态为STARTED 或者RESUMED 的时候(对应的生命周期方法onStart(),onResume(),onPause()执行过后),mActive 才会为true, 否则mActive 为false。
这时候再看dispatchingValue() 方法
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
#1 如果initiator 不为null, 单独下发事件给这个监听事件
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
#2 遍历LiveData 维护的监听事件列表,并下发事件
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
这里比较简单,#1当传入的具体的监听事件不为null 时,说明我们要单独下发给这个监听事件;#2 当传入的具体的监听事件为null 时,遍历LiveData 维护的监听事件列表并下发事件。
接着来到了considerNotify() 方法,
private void considerNotify(ObserverWrapper observer) {
#1 当前observer 状态mActive 为false 返回
if (!observer.mActive) {
return;
}
#2 再次检查observer 状态,如果为false,修改mActive
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
#3 调用observer 中维护的监听事件的onChanged()方法,也就是我们调用LiveData.observe(this)
{}方法的第二个参数
observer.mObserver.onChanged((T) mData);
}
这个方法中对当前ObserverWrapper 对象的活跃状态mAcive 进行检查,如果状态mActive 为false 则返回,否则调用我们注册监听事件时候传入的第二个参数Observer 对象的onChanged()方法,并传入需要下发的值。
以上是调用LiveData.observer() 方法后以及LifecycleOwner 生命周期变化时的执行流程。接着我们来看当我们主动调用LiveData.setValue() 或者LiveData.postValue() 的流程。
LiveData.setValue() :
protected void setValue(T value) {
#1 校验线程
assertMainThread("setValue");
mVersion++;
mData = value;
#2下发值
dispatchingValue(null);
}
可以看到非常简单,除了#1对主线程进行了校验外,就直接调用了dispatchingValue()方法,并且传入了null 作为参数,在上面我们说过当调用dispatchingValue()并传入null 时,会遍历LiveData 维护的监听对象然后下发值,这里就不再说明了。
LiveData.postValue() :
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
# 异步调用下发值
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
这里调用了ArchTaskExecutor 的postToMainThread() 方法,并将Runable 对象mPostValueRunable 当做参数传了进去,这里可以看到Runnable的run()方法也是直接调用了setValue()方法;
ArchTaskExecutor 是个线程管理工具类,它内部维护着一个线程数量为4的线程池 以及一个消息队列位于主线程的Handler 对象 mMainHandler
public class DefaultTaskExecutor extends TaskExecutor {
private final Object mLock = new Object();
private final ExecutorService mDiskIO = Executors.newFixedThreadPool(4, new ThreadFactory() {
private static final String THREAD_NAME_STEM = "arch_disk_io_%d";
private final AtomicInteger mThreadId = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName(String.format(THREAD_NAME_STEM, mThreadId.getAndIncrement()));
return t;
}
});
@Nullable
private volatile Handler mMainHandler;
@Override
public void executeOnDiskIO(Runnable runnable) {
mDiskIO.execute(runnable);
}
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = createAsync(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
@Override
public boolean isMainThread() {
return Looper.getMainLooper().getThread() == Thread.currentThread();
}
private static Handler createAsync(@NonNull Looper looper) {
if (Build.VERSION.SDK_INT >= 28) {
return Handler.createAsync(looper);
}
if (Build.VERSION.SDK_INT >= 16) {
try {
return Handler.class.getDeclaredConstructor(Looper.class, Handler.Callback.class,
boolean.class)
.newInstance(looper, null, true);
} catch (IllegalAccessException ignored) {
} catch (InstantiationException ignored) {
} catch (NoSuchMethodException ignored) {
} catch (InvocationTargetException e) {
return new Handler(looper);
}
}
return new Handler(looper);
}
}
最终通过mMainHander.post() 方法,将mPostValueRunable 插入到主线程的消息队列中,最终还是调用了LiveData.setValue() 完成了值的下发。
到此,LiveData的分析就结束了。