什么是LiveData
LiveData是一个可以被观察的数据持有类,它可以感知并遵循Activity,Fragment等组件的生命周期。由于LiveData对组件生命周期可感知的特点,所以我们可以在组件的生命周期处于激活状态的时候更新UI数据。
LiveData主要功能-- 传递数据
现有通信框架总结
| 通信方法 | 优点 | 缺点 |
|---|---|---|
| Handler | 系统原生,能实现线程间通信 | 高耦合 不利于维护 容易导致内存泄漏 |
| Broadcast | 简单 | 性能差,传播数据有限 打乱代码的执行逻辑 |
| interface | 速度快,容易理解 | 实现复杂,不利于维护 |
| rxbus | 效率高,无内存泄漏 | 基于rxjava,学习成本高且依赖包太大 |
| Eventbus | 使用简单 | 混淆问题,无法感知组件生命周期 实现复杂 |
简单使用
class MainActivity : AppCompatActivity() {
var binding: ActivityMainBinding ? = null
var liveData:MutableLiveData<String>?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding=DataBindingUtil.setContentView(this,R.layout.activity_main)
liveData = MutableLiveData();
val bean = User("arrom", 18);
binding?.user = bean
liveData?.observe(this, {
//更新UI
bean.name = "observe${it}"
bean.notifyChange()
Log.d("MainActivity","observe${it}")
})
binding?.clickBtn?.setOnClickListener {
Log.d("MainActivity","按钮点击事件")
liveData?.value = " livedata xujie-->>>>"
}
}
}
如果在子线程中发送消息请使用postValue
liveData?.postValue(" livedata xujie-->>>>")
源码分析
先来看一下观察者订阅的方法observe(),第一参数是LifecycleOwner,第二个参数是观察者,也是最后接收回调的地方
@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);
}
新建一个对象LifecycleBoundObserver,最后将LifecycleBoundObserver和LifecycleOwner进行了绑定
进入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) {
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);
}
}
可以看到这里面与LifecycleOwner进行了绑定,并且实现了onStateChanged方法,当生命周期发生变化时执行activeStateChanged(shouldBeActive());方法。
shouldBeActive
STATE 为STARTED/RESUMED就是说生命周期的方法为onStart()、onResume()、onPause()时都表示active,这3个状态都可以接收数据更新
onStateChanged
是GenericLifecycleObserver接口的方法,当生命周期变化的时候会回调它。这里会做判断,如果是已经destroy,直接移除观察者;否则会调用 activeStateChanged 方法。
//这里是调用了lifecycle的方法,如果Lifecycle 的 STATE 为`STARTED/RESUMED`则返回true
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
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);
}
}
LiveData类
/**
* Called when the number of active observers change to 1 from 0.
* <p>
* This callback can be used to know that this LiveData is being used thus should be kept
* up to date.
*/
protected void onActive() {
}
/**
* Called when the number of active observers change from 1 to 0.
* <p>
* This does not mean that there are no observers left, there may still be observers but their
* lifecycle states aren't {@link Lifecycle.State#STARTED} or {@link Lifecycle.State#RESUMED}
* (like an Activity in the back stack).
* <p>
* You can check if there are observers via {@link #hasObservers()}.
*/
protected void onInactive() {
}
要求生命周期至少是STARTED状态才被认为是activie状态;
如果state是DESTROYED状态时,解绑LifecycleOwner和LiveData
进入dispatchingValue方法
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//遍历LiveData的所有观察者
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
进入considerNotify方法
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//调用更新数据的方法
observer.mObserver.onChanged((T) mData);
}
LiveData的数据更新以及数据回调的整个过程大致如下。
setValue()其实最后就是通过调用了dispatchingValue()方法来实现的。
postValue方法
public void postValue(T value) {
super.postValue(value);
}
LiveData类
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
//切换到主线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
其他和setValue一样
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
LiveData原理
LiveData源码总结
- LiveData的观察者可以联动生命周期, 也可以不联动。在联动生命周期时,会自动在 DESTROYED 的状态下移除 Observer ,取消订阅,所以不用担心内存泄露;
- LiveData的观察者只能与一个LifecycleOwner绑定, 否则会抛出异常。而一个 owner 可以绑定多个 Observer 实例;
- LiveData 跟 LifecycleOwner 绑定,能感知生命周期变化,并且只会在 LifecycleOwner 处于 Active 状态(STARTED/RESUMED)下通知数据改变;如果数据改变发生在非 active 状态,数据会变化,但是不发送通知,等 owner 回到 active 的状态下,再发送通知;
- 使用observeForever()方法,会注意AlwaysActiveObserver对象,意味着给定的观察者将接收所有事件,并且永远不会被自动删除,不管在什么状态下都能接收到数据的更改通知
- LiveData 利用版本管理、绑定 Lifecycle 确保了只会发送最新的数据给 active 状态下的 Observer