一、LiveData简介
LiveData主要用于搭建MVVM架构,并在其中作为数据持有者,LiveData能监听组件的生命周期变化,这样一来只会更新处于活跃状态的组件。
LiveData的特点:
1)采用观察者模式,数据发生改变,可以自动回调(比如更新UI)。
2)不需要手动处理生命周期,不会因为Activity的销毁重建而丢失数据。
3)不会出现内存泄漏。
4)不需要手动取消订阅,Activity在非活跃状态下(pause、stop、destroy之后)不会收到数据更新信息
二、使用方法
在viewmodel 中这样使用:
public class TestViewModel extends ViewModel {
public final MutableLiveData<TesModel> mUserLiveData = new MutableLiveData<>();
public TestViewModel() {
mUserLiveData.postValue(new TesModel("25"));
}
public void doSomething() {
TesModel tesModel = mUserLiveData.getValue();
if (tesModel != null) {
mUserLiveData.setValue(tesModel);
}
}
}
在Activity 中这样使用:
testViewModel.mUserLiveData.observe(this, new Observer<TesModel>() {
@Override
public void onChanged(TesModel tesModel) {
}
});
使用非常简单,方便,完全不用考虑更新数据的时候UI的状态
三、源码分析
由于 LiveData 是一个 abstract class,他的实现类MutableLiveData
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
创建了Livedata 后,需要通过observe ,这个回调接口就是Observer
public interface Observer<T> {
/**
* Called when the data is changed.
* @param t The new data
*/
void onChanged(@Nullable T t);
}
//调用上面的方法来到了LiveData的observe()方法
//1. 传入的是LifecycleOwner和Observer(观察者)
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//2. 当前必须是在主线程
assertMainThread("observe");
//3. 当前的生命周期如果是DESTROYED状态,那么不好意思,不能观察了
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//4. 这里用装饰者模式将owner, observer封装起来
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//5. 将观察者缓存起来
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
.....
//6. 添加生命周期观察
owner.getLifecycle().addObserver(wrapper);
}
首先第1点,我们传入的是Activity,到里面却看到是LifecycleOwner.看AppCompatActivity源码
public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,
TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {
//中间省略
}
public class FragmentActivity extends ComponentActivity implements
ViewModelStoreOwner,
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompat.RequestPermissionsRequestCodeValidator {
// 中间省略
}
public class ComponentActivity extends Activity
implements LifecycleOwner, KeyEventDispatcher.Component {
}
AppCompatActivity的父类的父类(ComponentActivity)实现了LifecycleOwner接口,而LifecycleOwner接口是为了标识标记类有Android的生命周期的,
第2点,必须是主线程中.
第3点,如果生命周期是DESTROYED,那么不好意思,不能继续往下走了.
第4点,将owner, observer封装了起来,形成一个LifecycleBoundObserver对象
第5点我们看到有一个mObservers,它其实是LiveData里面的一个属性,是用来缓存所有的LiveData的观察者的.
我们在分析LifecycleOwner
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
在这个接口中只有一个方法用于返回Lifecycle ,Lifecycle的唯一实现类是LifecycleRegistry
public class LifecycleRegistry extends Lifecycle {
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
private final WeakReference<LifecycleOwner> mLifecycleOwner;
// 中间省略
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
// 中间省略
}
@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
mObserverMap.remove(observer);
}
// 中间省略
}
主要的成员变量mObserverMap和mLifecycleOwner,mObserverMap是一个Map结构,以观察者为key存储观察者状态。mLifecycleOwner是一个弱引用,持有LifecycleOwner,其实LifecyleOwner就是Activity或者Fragment。前面说到过Activity中会实现LifecycleOwner接口,其实追踪到源码发现ComponentActivity实现了LifecycleOwner接口,由此一来LifecycleRegistry就持有Activity的弱引用了,这样一来既能监听Activity的生命周期同时也不会造成内存泄漏
回过来头来在看LifecycleBoundObserver
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) {
// 当UI的生命周期为DESTROYED,取消对数据变化的监听,移除回调函数
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
类中封装了对于Lifecycle的状态赋值操作和状态改变对观察者进行取消订阅操作
我们继续看下activeStateChanged方法是如何对数据进行处理的,它是ObserverWrapper 类中的一个方法,
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) {
// 当前的生命周期和上一次的生命周期状态,是否发生变化,没有发生变化,就直接返回。
// onStart-onPause 为 true 在这之外的生命周期为false
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();
}
//结合上面的状态判断,我们知道了,生命周期状态从Inactive 到 Active, 就会调用回调函数
if (mActive) {
dispatchingValue(this);
}
}
}
如何得知数据已经更新
1. setValue()方式更新数据
来看LiveData的setValue()方法
private volatile Object mData = NOT_SET;
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
首先是当前必须是主线程,然后将值保存到了mData属性中.
void dispatchingValue(@Nullable ObserverWrapper initiator) {
......
//遍历所有的观察者执行considerNotify()方法
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
}
......
}
private void considerNotify(ObserverWrapper observer) {
......
observer.mObserver.onChanged((T) mData);
}
2. postValue()方式更新数据
volatile Object mPendingData = NOT_SET;
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
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;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
将value值赋值给mPendingData,然后通过ArchTaskExecutor的实例将mPostValueRunnable传入postToMainThread()方法.
ArchTaskExecutor 怎么处理的
public static ArchTaskExecutor getInstance() {
if (sInstance != null) {
return sInstance;
}
synchronized (ArchTaskExecutor.class) {
if (sInstance == null) {
sInstance = new ArchTaskExecutor();
}
}
return sInstance;
}
private ArchTaskExecutor() {
mDefaultTaskExecutor = new DefaultTaskExecutor();
mDelegate = mDefaultTaskExecutor;
}
public class DefaultTaskExecutor extends TaskExecutor {
@Nullable
private volatile Handler mMainHandler;
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
}
通过ArchTaskExecutor里面的DefaultTaskExecutor里面的postToMainThread()方法,其实将mPostValueRunnable交给了一个mMainHandler,这个mMainHandler有主线程的looper.可以方便的将Runnable搞到主线程. 所以最后mPostValueRunnable会到主线程中执行setValue(),毫无问题.