目录
1.1 postValue和setValue的区别以及怎么切换的线程
1.使用
var liveData = MutableLiveData<String>()
liveData.observe(this) {
Log.e("TAG", "lifecycleInit: $it")
}
liveData.setValue("2")
这三行代码不复杂,第一行进行实例化一个livedata对象,第二行进行绑定联系。最后一行设置数据。 其中setValue在主线程使用,postValue在子线程使用。我们先浅看一下postValue和setValue的区别。setValue咱们先看postValue,setValue后续看。
1.1 postValue和setValue的区别以及怎么切换的线程
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
咱们看到这个方法的最后一行,能看到切换到主线程,然后传了一个Runnable。我们来看看这个Runnable里有啥
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
这样就很显然了,切换到主线程之后,调用了setValue。这里切换线程使用的也是Handler来切换线程的。我就直接跳到关键步骤了。
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = createAsync(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
最终是调用到了DefaultTaskExecutor方法中的此方法,可以看出使用了Handler进行的线程切换。
2.observer方法
LiveData是如何进行绑定的呢?在我们想来他跟Activity/Fragment进行了生命周期的绑定,然后数据变化时咱们又可以监听到。这其实是如何做到的,这又是观察者又是被观察者的情况。让我们来看看它的observer方法()
@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);
.......
owner.getLifecycle().addObserver(wrapper);
}
咱们看这个方法,显示判断了执行的线程,然后判断被观察者(Activity/Fragment)的状态,如果是销毁的就没必要建立关联了。我们看到最后一行被观察者与wrapper建立关联,就猜出wrapper应该是观察者。我们来看看LifecycleBoundObserver类
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
.......
}
public interface LifecycleEventObserver extends LifecycleObserver {
/**
* Called when a state transition event happens.
*
* @param source The source of the event
* @param event The event
*/
void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}
这样咱们就知道,livedata是怎么和被观察者(Aactivity/Fragment)的生命周期进行绑定了,有了之前Liftcycle的基础。
3.响应
那接下来是如何进行响应的呢?既然跟其被观察者的生命周期建立了关系,咱们或许应该去之前Lifecycle中的代码中寻找,想想是ReportFragment中进行了相关调用。Lifecycle咱们已经说过了,直接跳到相关代码中。
observer.dispatchEvent(lifecycleOwner, event);
这在LifecycleRegistry类中的forwardPass和backwardPass方法中有调用到。咱们点击dispatchEvent中看详情。
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState);
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
这边调用了LifecycleEventObserver类中的onStateChanged,咱们刚才在绑定联系的时候,使用的是LifecycleBoundObserver类,它实现了LifecycleEventObserver,我们进入查看该方法的实现。
@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();
}
}
引入眼帘的就是判断被观察者的状态是否为销毁(DESTORYED),如果被销毁则移除并退出。然后调用shouldBeActive和activeStateChanged方法。我们先来看shouldBeActive
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
其进行被观察者的状态判断,判断其是否显示。STARTED,RESUME为显示。
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);
}
}
其中调用了changeActiveCounter方法,然后如果是显示的状态就执行dispatchingValue。先来看看changeActiveCounter方法。
@MainThread
void changeActiveCounter(int change) {
......
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;
}
}
显示时调用onActive方法,没显示调用onInactive方法。这两个方法liveData没有实现,是留给咱们可以自己处理自己想要的逻辑。
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;
}
这里边标记的变化,后续讲。先看其调用了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);
}
这个方法再次进行了判断是否显示,然后再进行了版本的判断,判断其是否为最新的版本。最后版本更新,调用咱们的观察者的onChanged方法。
4.ObserverForerver()
这是liveData提供的另一个订阅,从单词上我们可以知道是永远订阅。我们来看源码。
@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);
}
我们发现这里使用的是AlwaysActiveObserver类,再来我们没有看到生命周期的绑定,其实这个也能理解,永远订阅那咱们绑定生命周期没有任何意义。我们来看看,AlwaysActiveObserver的实现。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
它的sholdBeActive永远返回true,也就是永远是显示的。这也对Forever的单词有对应。值得注意的是这样的订阅,咱们最好在用完的时候,进行remove掉。
5.duspatchingValue方法的判断
我们先来看代码示例:
liveData = MutableLiveData<String>()
liveData.observe(this) {
Log.e("TAG", "lifecycleInit1: $it")
if (it.equals("1")) {
liveData.value = "2"
}
}
liveData.observe(this) {
Log.e("TAG", "lifecycleInit2: $it")
}
test_click.setOnClickListener(){
liveData.value = "1"
}
可以先猜猜,打印会是什么?1122?
结果是122!第二个observer的1没有显示。咱们来看看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和mDispatchInvalidated 。mDispatchingValue可以理解为防止递归,2一进来就直接被return掉了。mDispatchInvalidated可以字面理解分发是否失效。虽然2一进来就return掉了,但是它走之前把是否失效的标记改为了true。所以递归的return掉之后,第1个1走到if的判断后会直接break。之后再走到while的判断,此时是否失效为true,会重新走到循环里,此时for循环里面2个observer的value因为上次setValue("2")的关系,他们的value全是2了。于是打印了2个2。
6.setValue
其实这个没啥好讲了,咱们上头都讲了。直接上源码:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
其中做了主线程校验、版本增加、value赋值和执行disPatchingValue方法