一、LiveData简介
LiveData如同它的名字一样,是一个可观察的数据持有者,和常规的observable不同,LiveData是具有生命周期感知的,这意味着它能够在Activity、Fragment、Service中正确的处理生命周期。
LiveData的数据源一般是ViewModel,也可以是其它可以更新LiveData的组件。当数据更新后,LiveData 就会通知它的所有观察者,比如Activiy。与RxJava的方法不同的是,LiveData并不是通知所有观察者,它只会通知处于Active状态的观察者,如果一个观察者处于Paused或Destroyed状态,它将不会收到通知。
这对于Activiy和Service特别有用,因为它们可以安全地观察LiveData对象而不用担心内存泄漏的问题。开发者也不需要在onPause或onDestroy方法中解除对LiveData的订阅。还有一点需要注意的是一旦观察者重新恢复Resumed状态,它将会重新收到LiveData的最新数据。
二、LiveData的基本用法
LiveData是一个抽象类,它的最简单的实现类为MutableLiveData。
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);
}
}
- setValue方法必须在主线程使用;
- postValue方法可以在工作线程中使用;
1、LiveData在Activity中使用
public class MainActivity extends AppCompatActivity {
private static final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MutableLiveData<String> mutableLiveData = new MutableLiveData<>();
mutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable final String s) {
Log.d(TAG, "onChanged:"+s);
}
});
mutableLiveData.postValue("Android开发。。。");
}
}
- 创建对应数据类型的;
- 添加观察者与Lifecycle建立联系;
- 发送对应的数据进行更新;
2、LiveData中数据的更改
1.Transformations.map()
如果想要在LiveData对象分发给观察者之前对其中存储的值进行更改,可以使用Transformations.map()。
public class MainActivity extends AppCompatActivity {
private static final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MutableLiveData<String> mutableLiveData = new MutableLiveData<>();
mutableLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable final String s) {
Log.d(TAG, "onChanged1:"+s);
}
});
LiveData transformedLiveData =Transformations.map(mutableLiveData, new Function<String, Object>() {
@Override
public Object apply(String name) {
return name + "+Android开发者";
}
});
transformedLiveData.observe(this, new Observer() {
@Override
public void onChanged(@Nullable Object o) {
Log.d(TAG, "onChanged2:"+o.toString());
}
});
mutableLiveData.postValue("Android最牛逼的语言");
}
}
通过Transformations.map(),在mutableLiveData的基础上又加上了字符串。
打印结果:
D/MainActivity: onChanged1:Android最牛逼的语言
D/MainActivity: onChanged2:Android最牛逼的语言+Android开发者
2.Transformations.switchMap()
如果想要手动控制监听其中一个的数据变化,并能根据需要随时切换监听,这时可以使用Transformations.switchMap(),它和Transformations.map()使用方式类似,只不过switchMap()必须返回一个LiveData对象。
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
MutableLiveData<String> mutableLiveData1;
MutableLiveData<String> mutableLiveData2;
MutableLiveData<Boolean> liveDataSwitch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mutableLiveData1 = new MutableLiveData<>();
mutableLiveData2 = new MutableLiveData<>();
liveDataSwitch = new MutableLiveData<Boolean>();
LiveData transformedLiveData= Transformations.switchMap(liveDataSwitch, new Function<Boolean, LiveData<String>>() {
@Override
public LiveData<String> apply(Boolean input) {
if (input) {
return mutableLiveData1;
} else {
return mutableLiveData2;
}
}
});
transformedLiveData.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable final String s) {
Log.d(TAG, "onChanged:" + s);
}
});
liveDataSwitch.postValue(false);//2
mutableLiveData1.postValue("Android开发者");
mutableLiveData2.postValue("Android语言无敌");
}
}
新建一个MutableLiveData<Boolean>()来控制切换并赋值给liveDataSwitch,当liveDataSwitch的值为true时返回mutableLiveData1,否则返回mutableLiveData2。达到了切换监听的目的。
如果liveDataSwitch.postValue(false),打印Android语言无敌;
如果liveDataSwitch.postValue(true),打印Android开发者;
3、合并多个LiveData数据源
MediatorLiveData继承自mutableLiveData,它可以将多个LiveData数据源集合起来,可以达到一个组件监听多个LiveData数据变化的目的。
public class MainActivity extends AppCompatActivity {
private static final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MutableLiveData<String> mutableLiveData1 = new MutableLiveData<>();
MutableLiveData<String> mutableLiveData2 = new MutableLiveData<>();
MediatorLiveData liveDataMerger = new MediatorLiveData<String>();
liveDataMerger.addSource(mutableLiveData1, new Observer() {
@Override
public void onChanged(@Nullable Object o) {
Log.d(TAG, "onChanged1:"+o.toString());
}
});
liveDataMerger.addSource(mutableLiveData2, new Observer() {
@Override
public void onChanged(@Nullable Object o) {
Log.d(TAG, "onChanged2:"+o.toString());
}
});
liveDataMerger.observe(this, new Observer() {
@Override
public void onChanged(@Nullable Object o) {
Log.d(TAG, "onChanged:"+o.toString());
}
});
mutableLiveData1.postValue("Android进阶之光");
}
}
通过MediatorLiveData的addSource将两个MutableLiveData合并到一起,这样当任何一个MutableLiveData数据发生变化时,MediatorLiveData都可以感知到。
4、自定义LiveData对象
如果观察者的生命周期处于STARTED或RESUMED状态,LiveData会将观察者视为处于Active状态 。
public class MyLiveData extends LiveData<BigDecimal> {
private static MyLiveData sInstance;
@MainThread
public static MyLiveData get(String content) {
if (sInstance == null) {
sInstance = new MyLiveData(content);
}
return sInstance;
}
private MyLiveData(String content) {
}
@Override
protected void onActive() {
}
@Override
protected void onInactive() {
}
}
对LiveData进行了拓展,实现了LiveData的两个空方法onActive和onInactive。当Active状态的观察者的数量从0变为1时会调用onActive方法,通俗来讲,就是当LiveData对象具有Active状态的观察者时调用onActive方法,当LiveData对象没有任何Active状态的观察者时调用onInactive方法。
三、LiveData的原理
LiveData源码
public abstract class LiveData<T> {
@SuppressWarnings("WeakerAccess")
final Object mDataLock = new Object();
static final int START_VERSION = -1;
@SuppressWarnings("WeakerAccess")
static final Object NOT_SET = new Object();
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
@SuppressWarnings("WeakerAccess")
int mActiveCount = 0;
private boolean mChangingActiveState;
private volatile Object mData;
@SuppressWarnings("WeakerAccess")
volatile Object mPendingData = NOT_SET;
private int mVersion;
private boolean mDispatchingValue;
@SuppressWarnings("FieldCanBeLocal")
private boolean mDispatchInvalidated;
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
public LiveData(T value) {
mData = value;
mVersion = START_VERSION + 1;
}
public LiveData() {
mData = NOT_SET;
mVersion = START_VERSION;
}
@SuppressWarnings("unchecked")
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);
}
@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 {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
@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);
}
@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);
}
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
assertMainThread("removeObserver");
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
removed.detachObserver();
removed.activeStateChanged(false);
}
@SuppressWarnings("WeakerAccess")
@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
assertMainThread("removeObservers");
for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
if (entry.getValue().isAttachedTo(owner)) {
removeObserver(entry.getKey());
}
}
}
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
@SuppressWarnings("unchecked")
@Nullable
public T getValue() {
Object data = mData;
if (data != NOT_SET) {
return (T) data;
}
return null;
}
int getVersion() {
return mVersion;
}
protected void onActive() {
}
protected void onInactive() {
}
@SuppressWarnings("WeakerAccess")
public boolean hasObservers() {
return mObservers.size() > 0;
}
@SuppressWarnings("WeakerAccess")
public boolean hasActiveObservers() {
return mActiveCount > 0;
}
@MainThread
void changeActiveCounter(int change) {
int previousActiveCount = mActiveCount;
mActiveCount += change;
if (mChangingActiveState) {
return;
}
mChangingActiveState = true;
try {
while (previousActiveCount != mActiveCount) {
boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
previousActiveCount = mActiveCount;
if (needToCallActive) {
onActive();
} else if (needToCallInactive) {
onInactive();
}
}
} finally {
mChangingActiveState = false;
}
}
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) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
static void assertMainThread(String methodName) {
if (!ArchTaskExecutor.getInstance().isMainThread()) {
throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
+ " thread");
}
}
}
1、LiveData观察组件生命周期变化
通过observe方法观察生命周期变化
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//如果被观察者的当前的状态是DESTROYED,就return
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
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);
}
- owner实际上就是注册时传进来来组件,比如Activity,获取组件当前的状态,如果状态为DESTROYED,那么直接return,这说明DESTROYED状态的组件是不允许注册的。
- 新建了一个LifecycleBoundObserver包装类,将owner和observer传了进去。
- 将observer和LifecycleBoundObserver存储到SafeIterableMap<Observer<? super T>, ObserverWrapper>mObservers中,putIfAbsent方法和put方法有区别,如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,返回null。
- 如果等于null,将LifecycleBoundObserver添加到Lifecycle中完成注册,这样当我们调用LiveData的observe方法时,实际上是LiveData内部完成了Lifecycle的观察者的添加,这样LiveData自然也就有了观察组件生命周期变化的能力。
2、LiveData的observe方法回调
LifecycleBoundObservers是LiveData的内部类
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) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
LifecycleBoundObserver继承了ObserverWrapper类,重写了shouldBeActive方法,用于判断当前传入的组件的状态是否是Active的,Active状态包括STARTED和RESUMED状态。
LifecycleBoundObserver实现了LifecycleEventObserver接口,当组件状态发生变化时,会调用onStateChanged方法,当组件处于DESTROYED状态时,会调用removeObserver方法,来移除observer。保证一个观察者(组件)处于DESTROYED状态时,它将不会收到通知。
ObserverWrapper类是LiveData的内部类
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
activeStateChanged方法定义在抽象类ObserverWrapper中,它是Observer的包装类,activeStateChanged方法会根据Active状态和处于Active状态的组件的数量,来对onActive方法和onInactive方法回调,这两个方法用于拓展LiveData对象。如果是Active状态,会调用dispatchingValue方法,并将自身传进去。
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;
}
mDispatchingValue用于标记当前是否处于分发状态中,如果处于该状态,则当前分发无效,直接return。一路调用过来,ObserverWrapper是不为null的,无论是不是null,都会调用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);
}
considerNotify方法中做了多次的判断
- 如果ObserverWrapper的mActive值不为true,就直接return。
- 如果当前observer对应组件的状态不是Active,就会再次调用activeStateChanged方法,并传入false,其方法内部会再次判断是否执行onActive方法和onInactive方法回调。
- 如果判断条件都满足会调用Observer的onChanged方法,这个方法正是使用LiveData的observe方法的回调。
3、LiveData的postValue/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);
}
};
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
- postValue/setValue方法都定义在LiveData中;
- postValue方法实际上就是将setValue方法切换到主线程调用。
- setValue方法是运行在主线程中的,其内部调用了dispatchingValue方法,也就是dispatchingValue方法的参数ObserverWrapper为null的情况。
无论是LiveData的observe方法还是LiveData的postValue/setValue方法都会调用dispatchingValue方法。
网友评论