LiveData使用和原理

Posted by alonealice on 2020-05-13

LiveData是什么

LiveData 是一个可以保存数据和观察数据变化的组件,主要是被设计用来在ViewModel中保存数据。LiveData是一个可被观察的数据持有者类,这个跟RxJava的Observable有点类似。但与Observable不同,LiveData能够感知到应用程序组件的生命周期变化。因此它能遵守Activity、Fragment、Service等组件的生命周期,这样LiveData只更新处于活跃状态的应用程序组件Observer。这对于Activity和Fragment尤其有用,当Activity和Fragment生命周期为destory时,它们立即会被取消订阅,因为它们可以安全地订阅LiveData对象,而不必担心内存泄漏。

LiveData的特点

实时更新UI状态:LiveData遵循观察者模式,每次数据有变化时,LiveData会向Observer发出通知,开发者可以把更新UI的代码合并在这些Observer对象中,在Observer中及时更新UI。

避免内存泄漏:Observer会绑定具有生命周期的对象,并在这个绑定的对象被销毁后自行清理。

非活跃状态下安全:如果Observer的生命周期处于非活跃状态,就不会收到任何LiveData事件的通知,确保了这种状态下的安全性。

自动管理生命周期:Observer会感知到相应组件的生命周期变化,自动去停止或恢复观察。

及时更新最新数据:如果一个对象的生命周期变到非活跃状态,它将在再次变为活跃状态时接收最新的数据,确保了数据的及时性。同时当Activity或Fragment由于配置更改(如设备旋转)而重新创建时,也会收到最新的数据。

共享数据资源:在单例中扩展LiveData对象,就可以在应用程序中进行共享数据。

如何使用

添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
allprojects {
repositories {
jcenter()
google()
}
}

dependencies {
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:1.1.1"
// alternatively, just ViewModel
implementation "android.arch.lifecycle:viewmodel:1.1.1"
// alternatively, just LiveData
implementation "android.arch.lifecycle:livedata:1.1.1"

annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
}

创建LiveData对象

LiveData其实就是一个可以与任何数据一起使用的包装器。

1
2
3
4
5
6
7
8
9
public class NameData {
private MutableLiveData<String> mCurrentName;
public MutableLiveData<String> getName() {
if (mCurrentName == null) {
mCurrentName = new MutableLiveData<>();
}
return mCurrentName;
}
}

使用LiveData对象

创建并Tina建观察者observer,同时在适当的时机添加修改数据

1
2
3
4
5
6
7
nameData = new NameData();
nameData.getName().observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
textView.setText(s);
}
});
1
nameData.getName().setValue("添加测试文本");

自定义LiveData

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class NameLiveData extends LiveData<String> {

@Override
protected void onActive() {
super.onActive();
}

@Override
protected void onInactive() {
super.onInactive();
}

@Override
protected void setValue(String value) {
super.setValue(value);
}
}
  • onActive() :当LiveData依附在observer上时调用,比如添加时,或者从后台返回页面时。
  • onInactive() :当LiveData不在依附在observer上时调用,比如页面退到后台时,或则页面关闭时
  • setValue(T):更新LiveData实例的值并通知观察者

LiveData转换

Lifecycle软件包提供Transformations类,可以将LiveData转化为另一个封装其他数据的LiveData。

1
2
3
4
5
6
LiveData<Integer> a = Transformations.map(nameData.getName(), new Function<String, Integer>() {
@Override
public Integer apply(String input) {
return input.hashCode();
}
});
1
2
3
4
5
6
LiveData<Integer> liveData = Transformations.switchMap(nameData.getName(), new Function<String, LiveData<Integer>>() {
@Override
public LiveData<Integer> apply(String input) {
return null;
}
});

LiveData源码分析

observe方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);
}

在observe 方法中会创建LifecycleBoundObserver,同时会将observer和wrapper存到mObservers 队列中,并在activity中添加生命周期的监听。

LifecycleBoundObserver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@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(LifecycleOwner source, 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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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);
}
}

LifecycleBoundObserver 继承自 ObserverWrapper 而且实现 GenericLifecycleObserver接口,它会通过监听组件的生命周期变化回调onStateChanged方法。在onStateChanged方法中会根据是否生命周期大于STARTED ,调用onActive方法和onInactive。

observeForever方法

observeForever方法跟observe相似,但是它会注册一个没有关联生命周期的观察者对象。主要是它会创建一个AlwaysActiveObserver对象,而AlwaysActiveObserver是一直活跃的。

1
2
3
4
5
6
7
8
9
10
11
private class AlwaysActiveObserver extends ObserverWrapper {

AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}

@Override
boolean shouldBeActive() {
return true;
}
}

setValue方法

在setValue方法中会检查检查,setValue必须要求在主线程中执行。同时更新数据,版本+1,同时调用dispatchingValue方法通知所有的观察者。dispatchingValue如果传入null则是所有的观察者,如果是具体的ObserverWrapper对象,则通知到具体的Observer。

1
2
3
4
5
6
7
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}

如果传入的ObserverWrapper为null,那么就会遍历所有的ObserverWrapper,调用considerNotify通知观察者。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}

在considerNotify中对检查对应的生命周期和版本,最终调用onChanged方法通知。

postValue方法

postValue方法可以在线程中调用,其主要是通过ArchTaskExecutor,在主线程中执行setValue方法。

1
2
3
4
5
6
7
8
9
10
11
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

ArchTaskExecutor

ArchTaskExecutor是单例模式,里面会创建一个DefaultTaskExecutor,最终的方法postToMainThread会在DefaultTaskExecutor执行。

1
2
3
4
5
6
7
8
9
10
11
public static ArchTaskExecutor getInstance() {
if (sInstance != null) {
return sInstance;
}
synchronized (ArchTaskExecutor.class) {
if (sInstance == null) {
sInstance = new ArchTaskExecutor();
}
}
return sInstance;
}
1
2
3
4
private ArchTaskExecutor() {
mDefaultTaskExecutor = new DefaultTaskExecutor();
mDelegate = mDefaultTaskExecutor;
}

DefaultTaskExecutor

DefaultTaskExecutor里面对线程池用来在线程中执行,也有postToMainThread方法在主线程中执行runnable。

1
2
3
4
5
6
7
8
9
10
11
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}