一、LiveData简介
LiveData是google官方架构JetPack系列的一个响应式开发框架,LiveData是一个可以被观察的数据持有者类。说到响应式开发或者说观察者就不免想到RxJava,RxJava将观察者模式运用的炉火纯青。但LiveData和RxJava的定位是不一样的,LiveData主要用于搭建MVVM架构,并在其中作为数据持有者,LiveData能监听组件的生命周期变化,这样一来只会更新处于活跃状态的组件。
LiveData的特点:1)采用观察者模式自动提示UI更新。2)不需要手动处理生命周期,不会因为Activity的销毁重建而丢失数据。3)不会出现内存泄漏。4)不需要手动取消订阅,Activity在非活跃状态下(销毁、finish之后)不会收到数据更新信息。
二、LiveData用法
1)LiveData往往结合于ViewModel使用,对于ViewModel的分析之前已经进行分析了,这里不再过多描述。首先在ViewModel中创建LiveData,代码如下:
class MainViewModel : ViewModel() {
private val repertory: MainRepositoryby lazy { MainRepository()}
var data: MutableLiveData = MutableLiveData()
fun getDataFromServer(){
repertory.getDataFromServer(data)
}
}
这里采用的是MutableLiveData,它是LiveData的实现类,LiveData是一个抽象类。
2)在Activity中观察LiveData的数据变化。代码如下:
class MainActivity : AppCompatActivity() {
private lateinit var mModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initData()
}
private fun initData() {
mModel = ViewModelProviders.of(this)[MainViewModel::class.java]
mModel.data?.observe(this, Observer {
val mainAdapter = MainAdapter(this, it)
val linearLayoutManager = LinearLayoutManager(this)
rv.layoutManager = linearLayoutManager
rv.adapter = mainAdapter
})
mModel.getDataFromServer()
}
}
3)对LiveData进行赋值,代码如下:
fun postData() {
mModel.data.postValue(JsonBean(ArrayList(), 0, ""))
}
三、源码分析
1)首先先从实例化MutableLiveData入手,MutableLiveData是LiveData的实现类,源码如下:
public class MutableLiveData extends LiveData {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
从代码中可以看到,LiveData是一个泛型类,泛型参数就是存储数据的实际类型,同时MutableLiveData提供两个赋值方法:postValue和setValue,而这两个方法直接调用父类中的方法。所以看一下父类中这两个方法的具体实现
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
setValue方法必须在主线程调用,调用只有LiveData就持有新的数据了。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
postValue方法同样是更新LiveData持有的数据,但区别在于postValue方法是单独采用Runnable通过主线程handler发送给主线程更新数据,这样一来postValue就可以在异线程更新数据了。其实postValue最终更新数据还是走的setValue方法。
2)分析在Activity中订阅LiveData的方法observe,此方法接收两个参数,一个LifecycleOwner和Observer,代码如下:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
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);
}
从中我们可以发现方法首先会判断当前视图状态是否已经是”DESTROYED“状态,在分析订阅方法之前先分析一下LifecycleOwner这个接口。
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
在这个接口中只有一个方法用于返回Lifecycle。查看一下接口的实现类可以发现v4和v7包下的Acvitity和Fragment都实现了这个接口。接下来看一下Lifecycle这个抽象类。
public abstract class Lifecycle {
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
@MainThread
@NonNull
public abstract State getCurrentState();
.....省略部分代码
}
类中定义了添加和移除订阅者的方法,同时还包括订阅者的生命周期状态信息。而Lifecycle的唯一实现类是LifecycleRegistry,代码如下。
public class LifecycleRegistry extends Lifecycle {
private FastSafeIterableMap mObserverMap = new FastSafeIterableMap<>();
private final WeakReference mLifecycleOwner;
private int mAddingObserverCounter = 0;
private boolean mHandlingEvent = false;
private boolean mNewEventOccurred = false;
private ArrayList mParentStates = new ArrayList<>();
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
......省略部分代码
private boolean isSynced() {
if (mObserverMap.size() == 0) {
return true;
}
State eldestObserverState = mObserverMap.eldest().getValue().mState;
State newestObserverState = mObserverMap.newest().getValue().mState;
return eldestObserverState == newestObserverState && mState == newestObserverState;
}
private State calculateTargetState(LifecycleObserver observer) {
Entry previous = mObserverMap.ceil(observer);
State siblingState = previous != null ? previous.getValue().mState : null;
State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1)
: null;
return min(min(mState, siblingState), parentState);
}
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
private void popParentState() {
mParentStates.remove(mParentStates.size() - 1);
}
private void pushParentState(State state) {
mParentStates.add(state);
}
@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
mObserverMap.remove(observer);
}
@NonNull
@Override
public State getCurrentState() {
return mState;
}
static State getStateAfter(Event event) {
switch (event) {
case ON_CREATE:
case ON_STOP:
return CREATED;
case ON_START:
case ON_PAUSE:
return STARTED;
case ON_RESUME:
return RESUMED;
case ON_DESTROY:
return DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException("Unexpected event value " + event);
}
private static Event downEvent(State state) {
switch (state) {
case INITIALIZED:
throw new IllegalArgumentException();
case CREATED:
return ON_DESTROY;
case STARTED:
return ON_STOP;
case RESUMED:
return ON_PAUSE;
case DESTROYED:
throw new IllegalArgumentException();
}
throw new IllegalArgumentException("Unexpected state value " + state);
}
private static Event upEvent(State state) {
switch (state) {
case INITIALIZED:
case DESTROYED:
return ON_CREATE;
case CREATED:
return ON_START;
case STARTED:
return ON_RESUME;
case RESUMED:
throw new IllegalArgumentException();
}
throw new IllegalArgumentException("Unexpected state value " + state);
}
.....省略部分代码
}
先来看一下主要的成员变量mObserverMap和mLifecycleOwner,mObserverMap是一个Map结构,以观察者为key存储观察者状态。mLifecycleOwner是一个弱引用,持有LifecycleOwner,其实LifecyleOwner就是Activity或者Fragment。前面说到过Activity中会实现LifecycleOwner接口,其实追踪到源码发现SupportActivity实现了LifecycleOwner接口,同时声明变量LifecycleRegistry,代码如下:
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
由此一来LifecycleRegistry就持有Activity的弱引用了,这样一来既能监听Activity的生命周期同时也不会造成内存泄漏。接下来看关键的订阅和取消订阅方法,取消订阅很简单就是将观察者移除Map集合,订阅方法会先校验观察者的生命周期状态,同时从软引用中获取LifecycleOwner,如果为空的话则说明界面已经被销毁了,则不需要进行订阅了。否则进行订阅操作。
现在回到前面继续分析LiveData的订阅操作,订阅操作会将owner和observer统一包装成LifecycleBoundObserver,这是Lifecycle真正的订阅者。
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer 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);
}
}
类中封装了对于Lifecycle的状态赋值操作和状态改变对观察者进行取消订阅操作。最后将LifecycleBoundObserver传入LifecycleRegistry完成订阅。整体的订阅流程就分析完了。
3)Observer响应获取数据变化流程分析。
分析完订阅流程接下来分析LiveData如何响应数据变化通知给订阅者,这里需要从setValue方法入手。
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
private 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, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
调用setValue方法后会调用dispatchingValue方法循环通知订阅者响应数据变化。
三、LiveData特点原理总结
1)采用观察者模式自动提示UI更新:
由于采用订阅方式获取数据变化所以自动获取数据更新。
2)不需要手动处理生命周期,不会因为Activity的销毁重建而丢失数据:
会自动重新订阅。
3)不会出现内存泄漏:
Lifecycle持有的是Activity(Fragment)的弱引用。
4)不需要手动取消订阅,Activity在非活跃状态下(销毁、finish之后)不会收到数据更新信息:
LifecycleRegistry会回调Activity的状态,在onDestory之后LiveData自动取消订阅。