LiveData是什么?
可观察的数据存储类,就有生命周期感知能力,遵循(Activity、Fragment、Service)的生命周期
可以确保LiveData仅更新处在活跃生命周期的应用组件观察者。
基本使用
object MyLiveData {
// 创建LiveData实例
val data1: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
}
class MyService : Service() {
override fun onBind(p0: Intent?): IBinder? = null
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
thread {
for (i in 1..100000) {
Log.d("server", "消息内容是$i ")
// LiveData 发送消息,后台线程使用postValue
// 主线程使用 setValue() 即可
MyLiveData.data1.postValue("服务器给你推送消息啦,消息内容是$i")
Thread.sleep(2000)
}
}
return super.onStartCommand(intent, flags, startId)
}
}
MyLiveData.info1.observe(this, {
textView.text = it
})
LiveData源码分析
以下是订阅流程
// 1、第一个参数 持有被观察者Activity(代表宿主的生命周期当前的状态) ComponentActivity 会实现 LifecycleOwner 接口
// 宿主 == 生命周期
// onStart,onResume mActive = ture 代表存活
// 2、第二个参数 Observer
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
// 销毁状态做什么都不做 减少内存开销
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// Observer 单纯的接口 无法感知生命周期 只能通过(LifecycleBoundObserver)二次封装 来获取宿主的生命周期
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 将观察着存入到Map中
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
// owner == ComponentActivity
// owner.getLifecycle() == LifecycleRegistry()
owner.getLifecycle().addObserver(wrapper);
}
LifecycleBoundObserver
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@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);
}
// 每个生命周期都会调用的函数
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
// 自动帮你销毁 Observer
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
// 状态为存活继续往下走
// 进入父类 ObserverWrapper 的 activeStateChanged 方法
activeStateChanged(shouldBeActive());
}
}
ObserverWrapper
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
// 给外界暴露一个存活的方法
if (wasInactive && mActive) {
onActive();
}
// 给外界暴露一个不存活的方法
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
// LiveData中分发
dispatchingValue(this);
}
}
总结:订阅流程就是将观察者进行包装,与宿主的生命周期进行绑定,存活的才会进行分发,观察者获取数据
以下是发送数据的流程
@MainThread
protected void setValue(T value) {
// 判断是否在主线程
assertMainThread("setValue");
mVersion++;
mData = value;
// 进行数据的分发
dispatchingValue(null);
}
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// 观察者不为空走订阅流程,反之走赋值流程
if (initiator != null) {
// 订阅流程
considerNotify(initiator);
initiator = null;
} else {
// setValue 和 postValue 调用时
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
// mObservers 所有观察者的Map
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
// 时时刻刻 获取Lifecycle 的生命周期 判断是否存活 (存活:继续工作 不存活:销毁)
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
// 不断的递归 当页面显示出来
if (!observer.shouldBeActive()) {
// 最终绕到dispatchingValue
observer.activeStateChanged(false);
return;
}
// LiveData 的粘性数据
// observer.mLastVersion == -1 mVersion == 0
// 避免数据错乱
if (observer.mLastVersion >= mVersion) {
return;
}
// 版本对齐
observer.mLastVersion = mVersion;
// 分发数据给订阅者
observer.mObserver.onChanged((T) mData);
setValue、postValue流程
// 这里以postValue来举例,后面最终都会走回setValue
LiveData.postValue(value)
// 使用了开闭原则 装饰者模式 父类的复杂流程进行简化 暴露最简单的东西给用户
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
// 调用父类的 postValue方法
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
LiveData
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
// newValue 就是 postValue 传进来的 Value
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
// 最终还是要调用到 setValue
setValue((T) newValue);
}
};
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
// 切换到我们的主线程 通过Handler切换到主线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++; // 初始值 为 -1
mData = value; // 数据复制
// ObserverWrapper == null 遍历map 调用 considerNotify 方法
dispatchingValue(null);
}
Ps.
1、先订阅 后 setValue 收到消息 正确
2、先setValue 后订阅 也收到了消息 数据粘性 不正确
如何去掉数据粘性 : hook 反射 动态修改源码 就可以去除