写在前面:Jetpack的更新速度非常快,可能你一个月前看WorkManager是这样用的,下个月这个使用方法就有可能被废弃了(我看源码的时候是遇到过的,而且源码也变了,但核心原理是不变的),所以我们这一系列文章偏重讲原理,使用就一带而过(因为讲了也没用啊,会变的。。。。。,读者使用最好看官方文档官方文档
,当然我这里讲的也是截止到目前的最新用法)。
Jetpack使用(一)Lifecycles核心原理
Jetpack使用(二)LiveData核心原理
Jetpack使用(三)DataBinding核心原理
Jetpack使用(四)ViewModel核心原理
Jetpack使用(五)Navigation核心原理
Jetpack使用(六) WorkManager的4种用法
LiveData
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
- 活跃状态:STARTED 或 RESUMED状态
因为LiveData只会更新处于前台的activty的数据,所以LiveData具有以下
优点
- 不会发生内存泄露
观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。 - 不会因 Activity 停止而导致崩溃
如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。 - 不再需要手动处理生命周期
界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。 - 数据始终保持最新状态
如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
具体使用
- 创建 LiveData 对象
public class NameViewModel extends ViewModel {
private MutableLiveData currentName;
public MutableLiveData getCurrentName(){
if(currentName==null){
currentName=new MutableLiveData<>();
}
return currentName;
}
}
- 观察 LiveData 对象
public class NameActivity extends AppCompatActivity {
private NameViewModel model;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Other code to setup the activity...
// Get the ViewModel.
model = ViewModelProviders.of(this).get(NameViewModel.class);
// Create the observer which updates the UI.
final Observer nameObserver = new Observer() {
@Override
public void onChanged(@Nullable final String newName) {
// Update the UI, in this case, a TextView.
nameTextView.setText(newName);
}
};
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
model.getCurrentName().observe(this, nameObserver);
}
}
- 更新 LiveData 对象
btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
String anotherName="小三爷";
model.getCurrentName().setValue(anotherName);
}
});
注意:setValue在主线程使用;postValue在子线程使用
源码分析
我们从observe做为入口
@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);
}
一开始先判断observe观察者是不是在主线程,不是在在主线程就会报异常,
然后获得被观察者的生命周期,我们这里是actvity,然后判断是不是处于DESTROYED状态,如果处于DESTROYED直接返回,然后通过使用LifecycleBoundObserver把观察者和被观察者包装在一起,然后再把wrapper放到mObservers集合里,最后通过addObserver添加观察者,把观察者和被观察者的关系建立起来。
关系建立好之后,我们去看是怎么发送数据的,我们看到setValue的源码
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
这个这个方法也是在主线程里调用的,一开始也判断是不是主线程,然后mVersion版本++,这个变量后面再看,再把value存到LiveData的成员变量mData里,然后我们看到dispatchingValue方法里面,
@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, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
因为第一次传的是空,所以走到for循环里面,通过迭代器从mObservers取出每个观察者,然后调用considerNotify真正发送通知,
@SuppressWarnings("unchecked")
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.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
一开始observer如果不是活跃状态(STARTED 或 RESUMED状态)直接退出,再判断是不是应该被激活,如果不应该被激活,我们看看shouldBeActive方法
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
我们看到这个方法就是判断状态是不是大于等于STARTED,通过上一篇文章我们知道,比STARTED大的就是RESUMED,所以这里只有是状态STARTED或者RESUMED的时候才是返回 true的,所以这个if也就是判断是不是处于活跃状态,如果不是活跃状态进入activeStateChanged方法,
void activeStateChanged(boolean newActive) {
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();
}
if (mActive) {
dispatchingValue(this);
}
}
}
这里就是在统计LiveData里有没有活跃状态的,如果有就执行dispatchingValue,这次传的就不是null了,而是具体的liveData对象了,所以又走到之前的dispatchingValue方法里,只是这次走的是不为null的判断里,所以,这次再走到 if (observer.mLastVersion >= mVersion) {这个判断里,我们知道mLastVersion和mVersion初始值都是-1,但之前mVersion++了,不会return,所以最后,执行observer.mObserver.onChanged((T) mData);发送之前存的mData数据的操作。
- 注意: if (initiator != null) 参数传null和不传null的区别就是如果传null将会通知所有的观察者,反之仅仅通知传入的活跃的观察者
至此,我们LiveData的原理分析完了。