Potato
Potato copied to clipboard
AAC: LiveData
AAC: LiveData
[TOC]
对比 mvp 而言,使用大量的接口在 逻辑层和UI 层之间通信,AAC 则使用 livedata 进行通信。
基本使用
下面简单的演示如何在两者进行通信:
// MainActivity.java
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
bindData()
initView()
}
private fun bindData() {
Log.d(TAG, "MainActivity on create, ${lifecycle.currentState}")
lifecycle.addObserver(LifeCycleObject())
val addOneObserver = object : Observer<Int> {
override fun onChanged(t: Int?) {
Log.d(TAG, "-- $t ")
}
}
viewModel.resultLiveData.observe(this, addOneObserver)
}
private fun initView() {
addone.setOnClickListener { viewModel.addOne() }
}
class MainViewModel : ViewModel() {
var resultLiveData = MutableLiveData<Int>()
fun addOne() {
val value: Int? = resultLiveData.value
// dosomething
Log.d(TAG, "model -- $value")
resultLiveData.postValue((value ?: 0) + 1)
}
}
输出结果如下:
ainActivity: model -- null
D/MainActivity: -- 1
D/MainActivity: model -- 1
D/MainActivity: -- 2
D/MainActivity: model -- 2
D/MainActivity: -- 3
D/MainActivity: model -- 3
D/MainActivity: -- 4
可以看到无论调用 addOne() 几次,都在回调之前执行,只输入一次结果,带着问题往下看源码。
源码分析
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);
}
}
public abstract class LiveData<T> {
@SuppressWarnings("WeakerAccess") /* synthetic access */
final Object mDataLock = new Object();
static final int START_VERSION = -1;
@SuppressWarnings("WeakerAccess") /* synthetic access */
static final Object NOT_SET = new Object();
// map 保存观察者
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
...
}
下面看一下 bindData 的内容。
private fun bindData() {
Log.d(TAG, "MainActivity on create, ${lifecycle.currentState}")
lifecycle.addObserver(LifeCycleObject())
val addOneObserver = object : Observer<Int> {
override fun onChanged(t: Int?) {
Log.d(TAG, "-- $t ")
}
}
viewModel.resultLiveData.observe(this, addOneObserver)
}
val addOneObserver = object : Observer<Int> {
override fun onChanged(t: Int?) {
Log.d(TAG, "-- $t ")
}
}
public interface Observer<T> {
/**
* Called when the data is changed.
* @param t The new data
*/
void onChanged(T t);
}
// LiveData.java
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 必须在主线程
assertMainThread("observe");
// DESTROyED 状态不观察
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;
}
// 回到 LifeCycle
owner.getLifecycle().addObserver(wrapper);
}
下面看一下 ViewModel 的结果如何通知到 UI 层面。
// LiveData.java
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("a");
liveData.setValue("b");
b 首先会被设置,然后再设置a。
另外,如果在主线程执行完毕之前 post 多次结果,只有最后的一次结果会回调分发。
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
// 恢复状态
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 正在分发
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
// 对所有的观察者进行 value 分发
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
// 检查 UI 的状态,必须满足状态大于 STARTED。
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// value 更改的次数
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
// 回调通知新的 value。
observer.mObserver.onChanged((T) mData);
}
总结
LiveData 相当于 UI 和 ViewModel 之前的桥梁,当 UI 产生执行动作,而 ViewModel 执行逻辑,从数据库或者网络拿到数据后, 从不同线程使用 livedata postvalue 到 UI 进行操作。
是为 MVVM 架构, 也是数据驱动, 响应式编程的表现。