定义
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力.
意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。 这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。
我想从源码知道些什么内容
- 数据如何感知生命周期?
Tip:
源码:Android API 29
LiveData 的使用
// 1. 在 ViewModel 中创建 LiveData 对象
class NameViewModel : ViewModel() {
// Create a LiveData with a String
val currentName: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
// Rest of the ViewModel...
}
// 2. 在 组件中观察数据
class NameActivity : AppCompatActivity() {
// Use the 'by viewModels()' Kotlin property delegate
// from the activity-ktx artifact
private val model: NameViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 活跃状态下观察数据
model.currentName.observe(this, Observer<String> { newName ->
// Update the UI, in this case, a TextView.
nameTextView.text = newName
})
// 所有状态下都能观察数据
model.currentName.observeForever { user ->
// update UI
Log.e("currentName","currentName:$currentName")
}
// 3. 通知数据更新
button.setOnClickListener {
val anotherName = "John Doe"
model.currentName.value = anotherName
}
}
}
参考示例:
- Android Jetpack 库架构组件 ViewModel+LiveData 基础使用
通过使用我们可以找到几个关键点
-
MutableLiveData
是什么 -
MutableLiveData
的setValue()
是如何工作的 -
MutableLiveData
是如何通过observe
观察数据的
MutableLiveData
是什么
进入到MutableLiveData
源码发现它是继承了LiveData
,并没做多余的操作。
那我们为什么不直接使用LiveData
呢?
两个原因:
-
LiveData
是抽象类不能直接使用 - 设计成抽象类就是为了隐藏
LiveData
的内部实现,仅提供抽象方法给使用者。
public class MutableLiveData<T> extends LiveData<T> {
public MutableLiveData(T value) {
super(value);
}
public MutableLiveData() {
super();
}
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
上面的代码中可以看出重写了两个方法
- postValue
- setValue
方法名就像设置数据,那么这两个方法有什么区别呢?
MutableLiveData
的setValue()
是如何工作的
进入setValue
方法,通过源码和注释,我们就知道了setValue 和 postValue
的区别。
/**
* Sets the value. If there are active observers, the value will be dispatched to them.
* <p>
* This method must be called from the main thread. If you need set a value from a background
* thread, you can use {@link #postValue(Object)}
*
* @param value The new value
*/
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
// 订阅次数+1
mVersion++;
// 数据更新
mData = value;
// 分发指定的 ObserverWrapper
dispatchingValue(null);
}
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
// 子线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
- setValue 在主线程调用
- postValue 在子线程调用
这里的线程切换底层还是用的Handler
实现。只不过这里又多封装了一层TaskExecutor
我们进入到postToMainThread
方法
@Override
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
这里使用了mDelegate
代理,如果没有设置代理则使用默认的DefaultTaskExecutor
进入到DefaultTaskExecutor
可找到postToMainThread
的实现。
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = createAsync(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
ps:抽象类和子类,以及代理实现。让我又想起之前用
ARouter
做组件化开发使用的IProvider
接口。BaseModule
中定义接口,各个Module
中实现,如果Module
间需要联系即可通过BaseModule
中定义的接口方法调用到不同Module
在实现类的结果。
再回过头来看 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);
}
};
可以看出这里的postValue
还是会调用setValue
pps:源码中太多这种统一调用的操作了。比如 Retrofit 的同步异步调用,异步调用最后还是会执行同步方法。
setValue
中调用了分发数据的方法dispatchingValue(null)
:
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 在遍历通知各 ObserverWrapper 期间, 若数据发生了变化, 则会重新遍历
// mDispatchingValue = true 表示数据发生了变化
// mDispatchInvalidated = true 表示需要重新遍历
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
// 循环时:表示数据不需要重新遍历
mDispatchInvalidated = false;
// 若参数 initiator 非空,则只通知特定的 ObserverWrapper
// 否则遍历通知所有的 ObserverWrapper
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 通知观察者,这个观察者是 ObserverWrapper 类型的。
considerNotify(iterator.next().getValue());
// 若数据发生变化, 则退出for循环
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
// 循环结束,将数据需要遍历的标识符改为 false
mDispatchingValue = false;
}
// 而分发数据逻辑中就是循环遍历告知所有的观察者
private void considerNotify(ObserverWrapper observer) {
// 不在活跃状态,直接 return
if (!observer.mActive) {
return;
}
// 不是在活跃状态 则设置活跃状态为 false 且不去通知观察者,直接 return
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// mVersion 表示发送订阅的次数
// 当调用 setValue 之后 mVersion 会加1,所以说在数据发送变化时才会去通知观察者,否则直接 return
if (observer.mLastVersion >= mVersion) {
return;
}
// 更新最后一次通知观察者的版本号
observer.mLastVersion = mVersion;
// 通知观察者
observer.mObserver.onChanged((T) mData);
}
既然通知到位了,那接下来看注册的通知如何在活跃状态下更新数据。
MutableLiveData
是如何通过observe
观察数据的
我们调用observe
的去监听数据更新的代码如下:
model.userInfo.observe(this, Observer<User>{ user ->
// update UI
Log.e("GardenActivity","user:$user")
})
进入observe
源码可以看出该方法要在主线程调用,上面传入的this
参数是LifecycleOwner
,并通过这个LifecycleOwner
获取到LifeCycle
进而调用LifeCycle
的addObserver
方法实现数据对组件生命周期的感知。
// 只在活跃状态下接收数据
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 实现活跃状态检测的观察者
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
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.getLifecycle().addObserver(wrapper);
}
这里的addObserver(wrapper)
的参数传入了LifecycleBoundObserver
对象
进入LifecycleBoundObserver
可以查看到
- onStateChanged :
state
变化的回调,在DESTROYED
时将观察者移除 - detachObserver:在里面也移除了当前的观察者
可见在LiveDate
内部是处理内存泄漏的问题。
而且shouldBeActive
方法中返回了活跃状态,也就是组件只在活跃状态下更新数据
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() {
// 大于等于 STARTED 的值才是活跃的状态:这里就只有 STARTED 和 RESUMED
// STARTED:onStart()之后onPause()之前的生命周期
// RESUMED:onResume() 之前的生命周期
// 所以说 LiveData 只在活跃状态下更新数据,就是在:onStart()、onPause()、onResume() 这三个生命周期下会回调数据更新。
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
// 更改活跃状态
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
而跟LifecycleBoundObserver
相对于的是AlwaysActiveObserver
类,这个是保持所有的观察者都所欲活跃状态。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
相应的监听方法是observeForever
// 在所有状态下组件都接收数据
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
// 更改活跃状态
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) {
// 循环通知观察者
dispatchingValue(this);
}
}
addObserver
的实现是由LiveData
的实现类LifecycleRegistry
实现了。
关于LifeCycle
如何绑定生命周期,更多源码可以查看:带着问题看源码之 LifeCycler。
所以LiveData
中的数据能够感知组件的生命周期变化,实际上是用了LifeCycle
去实现。
总结
MutableLiveData
是什么
是LiveData
的实现类,提供了公开的postValue、setValue
方法用于数据改变MutableLiveData
的setValue()
是如何工作的
每次setValue
计数器加1,同时数据变为最新的数据,调用dispatchingValue(null)
分发指定的ObserverWrapper
当数据再次改变时会调用dispatchingValue(ObserverWrapper)
循环分发所有活跃状态的的数据。如果之前的数据还在下发则停止下发并重头开始下发MutableLiveData
是如何通过observe
观察数据的
这是在活跃状态下观察数据的方法,活跃状态是:onStart,onPause,onResume。
内部检测生命周期使用的是LifeCycle
库
与observe
对应的还有observeForever
,它能在所有状态下观察到数据。
参考
- LiveData 概览
- Android官方架构组件LiveData: 观察者模式领域二三事
- Android Jetpack 库架构组件 ViewModel+LiveData 基础使用