本文讲解 LiveData 用法,以及 LiveData 源码解析。
官方文档:https://developer.android.google.cn/topic/libraries/architecture/livedata
一句话介绍 LiveData :LiveData 是一种可观察的数据存储器类。
与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
为什么需要 LiveData:
注:本文使用 Kotlin 编写。
导入 LiveData 库:implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
一、用法
1. 自定义布局,一个 TextView ,两个 Button
2. 自定义 ViewModel 类,在 ViewModel 中改变 LiveData 数据的值。
class MainViewModel : ViewModel() {
val TAG = "MainViewModel"
val liveData = MutableLiveData()
var stop = false
fun start() {
liveData.postValue(0)
object : Thread() {
override fun run() {
while (!stop) {
sleep(1000)
val value = liveData.value
liveData.postValue(value?.plus(1))
Log.d(TAG, "run: " + liveData.value.toString())
}
}
}.start()
}
fun stop() {
stop = true
}
}
3. 在 Activity 里观察 LiveData
class MainActivity : AppCompatActivity() {
lateinit var mainViewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
mainViewModel.liveData.observe(this, Observer {
tv_content.text = it.toString()
})
btn_start.setOnClickListener {
mainViewModel.start()
}
btn_stop.setOnClickListener {
mainViewModel.stop()
}
}
}
4. 执行程序,点击 Start Button ,每隔1s,数据会发生改变;点击 Stop Button ,线程关闭,数据不再发生改变。
二、源码解析
1. MutableLiveData 源码:
public class MutableLiveData extends LiveData {
public MutableLiveData(T value) {
super(value);
}
public MutableLiveData() {
super();
}
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
MutableLiveData 是对 LiveData 的拓展。因为 LiveData 是一个 abstract 的 class ,并不能直接使用。
2. LiveData 类图:
观察上面的类图,它有两个实现类,一个是 MutableLiveData ,另一个是 MediatorLiveData 。内部包含了一个 LifecycleBoundObsOvserver ,它实现了 Lifecycle 的 Observer ,它里面的 Observer 进行了对组件生命周期的观察。所以 LiveData 才有了观察组件生命周期的能力。
LiveData 函数说明:
实现了 LifecycleEventObserver 接口,用来观察组件生命周期。
<
大体流程:LiveData post 或 set value 的时候,首先通过 hasObservers 判断是否有观察者,如果没有就不进行分发,如果有就通过 onActive 遍历是否是激活状态,如果是激活状态就会去调用 <
3. LiveData.observe() 源码
public void observe(LifecycleOwner owner, 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);
}
传进来的 owner 是 Activity 或 Fragment ,然后把 observer 观察者也传进来。
首先判断是否是 DESTROYED 状态,如果是就 return 。
然后会 new 一个 LifecycleBoundObserver ,用来处理生命周期。
把 wrapper put 到 mObservers 容器里面,这个容器是用来遍历用的。
owner 获取 getLifecycle ,添加生命周期观察者 addObserver 。
4. LiveData.postValue() 源码
protected void postValue(T value) {
...
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
因为它可以在子线程进行分发,所以它要 postToMainThread 到主线程去:
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
...
setValue((T) newValue);
}
};
它最终调的还是 setValue() 。所以说 setValue() 是在主线程进行调用。
5. LiveData.setValue() 源码
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
在 set 或 post 时,它的 mVersion 会更新一下,内部的 mData 会被赋值新的 value 。
6. LiveData.dispatchingValue() 源码
void dispatchingValue(ObserverWrapper initiator) {
// 判断是否正在进行分发动作,如果正在进行就直接 return 。
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
// 执行 do while 循环
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
// 遍历,通过 Map 进行存储
for (Iterator < Map.Entry < Observer < ?super T > , ObserverWrapper >> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext();) {
// 这里的 iterator.next() 对应的是 ObserverWrapper 。
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while ( mDispatchInvalidated );
mDispatchingValue = false;
}
7. LiveData.considerNotify() 源码
private void considerNotify(ObserverWrapper observer) {
// 判断是否是激活状态,如果是非激活状态直接 return 。
if (!observer.mActive) {
return;
}
// 判断是否是激活状态,如果是非激活状态直接 return 。
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 判断 当前版本 大于等于 LiveData 总的版本号,就不会继续分发。
if (observer.mLastVersion >= mVersion) {
return;
}
// 把当前的 Version 赋值给 observer 。
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
这个函数解释了 Activity 不会被重复回调的原因。
把 mData 传给当前的 observer 。比如我们的 MainActivity 里面的代码:
mainViewModel.liveData.observe(this, Observer {
...
})
public interface Observer {
void onChanged(T t);
}
最终会回调到 Observer {} 里去执行 tv_content.text = it.toString() 。
如果本文对你有帮助,请点赞支持!!!