Jetpack已经出来很久了,虽然挺好用但是说实话对其原理理解还是有限,所以抽空来研究一下Jetpack各个功能的原理。
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
通俗的说就是当liveData数据发生改变时,只有处于活跃状态的组件才能收到数据改变的回调。
对于LiveData来说不需要在build.gradle额外添加引用,只需在项目的build.gradle中加上google()库即可,一般新建工程时候默认就有引入了google()
allprojects {
repositories {
google()
jcenter()
}
}
首先先简单的演示LiveData的使用:
我们添加两个按钮,第一个是给LiveData添加注册函数,就是对它进行观察。第二个按钮用来改变LiveData所持有的数据。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册observer"
android:onClick="onClick"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="改变数据"
android:onClick="onClick2"/>
LinearLayout>
在对应的activity中进行相应的操作:
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.MutableLiveData;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
MutableLiveData<String> liveData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
liveData = new MutableLiveData<>();
//为livedata设置一个默认值 只能在主线程中调用 如果要在子线程中更新可以调用postValue(T)方法
liveData.setValue("liveData默认值");
}
public void onClick(View view) {
//点击第一个按钮 添加观察回调
liveData.observe(this,(String data)->{
Log.d("gsy","data change ="+data);
});
}
public void onClick2(View view) {
//改变liveData数据
liveData.setValue("改变了liveData的数据");
}
}
运行起来发现当点击注册按钮时会触发回调,打印如下log,是不是有点粘性事件的意思:
2020-09-09 16:46:38.704 8763-8763/com.***.livedata D/gsy: data change =liveData默认值
当点击改变数据时候打印如下log:
2020-09-09 16:46:53.770 8763-8763/com.***.livedata D/gsy: data change =改变了liveData的数据
当然实际开发中肯定不会这样写,observe和setValue方法要分别写在业务逻辑需要的地方,这里只是说明一下LiveData的基本使用。很多时候LiveData都是跟ViewModel配合使用,咱们先一步一步来吧,后面再讲ViewModel。我一般都是封装一个Bus类来保存LiveData:
import androidx.lifecycle.MutableLiveData;
import java.util.HashMap;
import java.util.Map;
public class LiveDataBus {
private static volatile LiveDataBus liveDataBus;
private Map<String, MutableLiveData<?>> liveDataMap;
private LiveDataBus(){
liveDataMap = new HashMap<>();
}
//DCL单例
public static LiveDataBus getInstance() {
if (liveDataBus == null) {
synchronized (LiveDataBus.class){
if (liveDataBus == null){
liveDataBus = new LiveDataBus();
}
}
}
return liveDataBus;
}
//存取一体
public<T> MutableLiveData<T> with(String key,Class<T> clazz){
if (!liveDataMap.containsKey(key)){
liveDataMap.put(key,new MutableLiveData<>());
}
return (MutableLiveData<T>) liveDataMap.get(key);
}
}
我个人看源码或者框架时候一般都是带着一个目的,因为源码性的东西一般比较复杂,不可能每行代码都能看懂。所以最好带着问题看源码。对于LiveData来说问题可以有如下两个:
1.下面就来进入源码中吧。首先先看注册观察的流程,
liveData.observe(this,(String data)->{
Log.d("gsy","data change 1 ="+data);
});
我这里用了lambda表达式,可能不熟悉的小伙伴会看的有点迷糊,我换一种写法大家应该都能明白:
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.d("gsy","data change 1 ="+s);
}
});
我们就点进去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需要传入两个参数,LifecycleOwner 和Observer。还记得注册时候吗,第一个参数我们传的是this,所以先找一下AppCompatActivity的父类,看哪个父类是实现了LifecycleOwner 这个接口。点了三次在一个叫ComponentActivity发现了如下代码:
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
原来是ComponentActivity 实现了LifecycleOwner的接口。继续回到observe方法:
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
这几行代码相信大家都能理解,如果组件当前是DESTROYED状态,就不去注册观察方法。接着new一个LifecycleBoundObserver ,它是LiveData的一个内部类:
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
新建一个 LifecycleBoundObserver 将我们的 LifecycleOwner 和 observer保存起来,然后调用 mObservers.putIfAbsent(observer, wrapper) 将observer和wrapper分别作为key和value存入Map中,mObservers 实际上是一个Map集合:
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
接下来看下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) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
LifecycleBoundObserver 继承自 ObserverWrapper 并实现了 GenericLifecycleObserver接口,而 GenericLifecycleObserver 接口又继承自 LifecycleObserver 接口,根据 Lifecycle 的特性,实现了LifecycleObserver接口并且加入 LifecycleOwner 的观察者里就可以感知或主动获取 LifecycleOwner 的状态。那么LifecycleBoundObserver 就具备了感知组件声明周期的能力。
到这一步注册还没算完,大家应该都知道当调用observe方法时,如果liveData之前执行过setValue或者postValue也会触发oberve的回调,意思就是先赋值再注册观察者,也会触发观察者回调,这部分逻辑也是在observe中,所以继续回到observe方法,在这个方法最后:
owner.getLifecycle().addObserver(wrapper);
addObserver是Lifecycle的抽象方法,真正实现的地方在LifecycleRegistry,继续跟踪addObserver方法:
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
//省略代码
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);
}
//省略代码
}
代码进入while循环,调用LifecycleRegistry的内部类ObserverWithState中的dispatchEvent方法:
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
//关键代码
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
先看下mLifecycleObserver,也就是LifecycleEventObserver,这是个接口,显然会有其实现类。
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);
}
LifecycleEventObserver接口的其中一个实现类就是LifecycleBoundObserver,所以这里就调用到了LifecycleBoundObserver的onStateChanged方法:
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//关键代码
activeStateChanged(shouldBeActive());
}
继续跟踪:
void activeStateChanged(boolean newActive) {
//省略
if (mActive) {
dispatchingValue(this);
}
}
注意传入参数不为null:
@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<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;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
前面两个判断都是跟生命周期有关,我们先不用关注,第三个if是关键所在,这俩变量初始值都是-1,所以看起来 这里就会return了,但是别忘了我们在调用obeserve之前设置了默认值。
int mLastVersion = START_VERSION;
private int mVersion = START_VERSION;
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
//关键代码
mVersion++;
mData = value;
dispatchingValue(null);
}
所以当走到if (observer.mLastVersion >= mVersion)这里时候,mLastVersion =-1,mVersion=0。所以代码会继续运行下去:
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
调用到注册时候的回调方法。这就是为啥LiveData设置值后再注册,也会触发回调的原因,当年可是被这个坑坑的不轻。到此第一个问题算是解决了。
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
将value赋值给mData ,然后调用dispatchingValue注意这里传入的是null:
@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<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
//关键代码
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
这就很明显了,从Map中取出保存的ObserverWrapper,然后在considerNotify中调用onChanged回调。代码比较简单就不再贴了。
LiveData使用在组件通信方面还是非常方便的,它主要是依赖于Lifecycle去实现的,其实现原理感觉在Jetpack中算是比较简单的了。关于生命周期这块就不再去写了,有兴趣的小伙伴可以去看下Lifecycle源码。