1 简介和简单使用
1.1 简介
LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData具有生命周期感知能力,意指它遵循其他应用组件(如Activity、Fragment或Service)的生命周期。这种感知能力可确保LiveData仅更新处于活跃生命周期(onStart、onResume)状态的应用组件观察者。LiveData通常和ViewModel相结合使用。
LiveData依赖于Lifecycle,需要使用Lifecycle提供的状态来判断程序的活跃状态。
如果观察者(由Observer类表示)的生命周期处于STARTED或RESUMED状态,则LiveData会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察LiveData对象而注册的非活跃观察者不会收到更改通知。
Google官网:https://developer.android.google.cn/topic/libraries/architecture/livedata?hl=zh_cn
1.2 简单使用
引入依赖,按需所取。
def lifecycle_version = "2.4.1"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
创建一个单例StrLiveData,里边会实例化一个MutableLiveData,用来存储String类型的数据。
object StrLiveData {
//懒加载
val info: MutableLiveData<String> by lazy { MutableLiveData() }
}
在Activity中使用。
class LiveDataActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
val tvContent = findViewById<TextView>(R.id.tv_content)
//观察数据变化,界面可见时,才会给TextView设置数据
StrLiveData.info.observe(this) {
tvContent.text = it
}
//观察数据变化,不管界面可见不可见,都给TextView设置数据
//observeForever不会考虑生命周期,任何状态下都会执行
StrLiveData.info.observeForever {
tvContent.text = it
}
//主线程修改数据
StrLiveData.info.value = "在主线程修改的数据"
thread {
Thread.sleep(2000)
//子线程修改数据
StrLiveData.info.postValue("在子线程修改的数据")
}
}
}
XML文件。
<?xml version="1.0" encoding="utf-8"?>
<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:gravity="center"
android:orientation="vertical"
tools:context=".jetpack.livedata.demo1.LiveDataActivity">
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
1.3 关系框架
2 源码分析
2.1 setValue 主线程修改数据
首先在业务层单例中实例化了一个MutableLiveData,MutableLiveData继承LiveData,只保留setValue和postValue两个设置数据的方法,简化使用。
public class MutableLiveData<T> extends LiveData<T> {
/**
* Creates a MutableLiveData initialized with the given {@code value}.
*
* @param value initial value
*/
public MutableLiveData(T value) {
super(value);
}
/**
* Creates a MutableLiveData with no value assigned to it.
*/
public MutableLiveData() {
super();
}
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
当业务层调用LiveData的setValue方法时,在主线程修改数据。
//主线程修改数据
StrLiveData.info.value = "在主线程修改的数据"</pre>
setValue方法首先会检查当前是否是主线程,然后会对mVersion+1,接着分发数据。
<pre data-language="java" id="QU8SA" class="ne-codeblock language-java" style="border: 1px solid #e8e8e8; border-radius: 2px; background: #f9f9f9; padding: 16px; font-size: 13px; color: #595959">@MainThread
protected void setValue(T value) {
//检查是否是主线程
assertMainThread("setValue");
//mVersion+1
mVersion++;
mData = value;
//分发数据
dispatchingValue(null);
}
mVersion是LiveData粘性数据特性的关键,它的初始值是-1。
static final int START_VERSION = -1;
public LiveData() {
mData = NOT_SET;
//LiveData实例化的时候给mVersion赋值为-1
mVersion = START_VERSION;
}
分发数据的时候有两种情况,一种是调用LiveData.observe(),另一种是调用LiveData.observeForever()。ObserverWrapper是观察者的包装类。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
...
//initiator(观察者)不为空
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//initiator(观察者)为空,需要遍历所有的观察者
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
...
}
接下来调用considerNotify方法。然后对当前是否是活跃状态进行检查,也就是mActive是否为true。为true才会继续执行。就这对mVersion进行对比,由于在setValue的时候mVersion++之后变为0,mLastVersion为-1,所以这里observer.mLastVersion >= mVersion不成立,数据会正常分发出去,这就是造成粘性数据特征的原因。
如果调用LiveData.observe(),那么当Lifecycle状态为STARTED和RESUMED,也就是Activity/Fragment生命周期为onStart和onResume的时候,mActive=true,其他状态和生命周期下,mActive=fale;如果调用LiveData.observeForever(),mActive一直为true,这就实现了调用LiveData.observeForever()时候,观察者不会去考虑生命周期和状态,所有数据都会无条件感知。
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
//判断mActivie是否为true。
//调用LiveData.observe()时会根据状态和生命周期计算mActive的值;
//调用LiveData.observeForever()时mActive一直为true。
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//判断mVersion
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//回调数据给观察者
observer.mObserver.onChanged((T) mData);
}
2.2 postValue 子线程修改数据
当业务层调用LiveData的postValue方法时,在子线程修改数据。
thread {
...
//子线程修改数据
StrLiveData.info.postValue("在子线程修改的数据")
}
postValue方法中最终也会通过Handler切换到主线程。
protected void postValue(T value) {
boolean postTask;
//加锁,防止线程安全问题
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
//切换到主线程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
在ArchTaskExecutor中,会实例化一个DefaultTaskExecutor,然后调用DefaultTaskExecutor的postToMainThread方法。
private ArchTaskExecutor() {
mDefaultTaskExecutor = new DefaultTaskExecutor();
mDelegate = mDefaultTaskExecutor;
}
@Override
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
DefaultTaskExecutor使用Handler进行线程间通信,实现子线程到主线程切换。
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
而在postToMainThread中传入的Runnable中,最红也调用了setValue,接下来的逻辑就和主线程中修改数据一致了。
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//最终也是调用setValue
setValue((T) newValue);
}
};
2.3 observe 根据生命周期感知数据变化
调用LiveData的observe( LifecycleOwner owner, Observer<? super T> observer)方法时,传入了一个被观察者和观察者。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//检查是否是主线程
assertMainThread("observe");
//获取Lifecycle当前状态,如果是销毁状态,那就忽略,不再继续往下进行
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
//创建一个LifecycleBoundObserver对象,包装了LifecycleOwner和Observer。
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//ObserverWrapper包装了LifecycleBoundObserver和Observer
//把Observer和LifecycleBoundObserver存入map
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);
}
LifecycleBoundObserver是LiveData的内部类,继承了ObserverWrapper,并且实现LifecycleObserver。传入了一个被观察者和观察者。
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
//传入被观察者和观察者
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
//从Lifecycle获取到当前是否是活跃状态(UI可见状态)。
//Activity/Fragment生命周期onStart和onResume,Lifecycle对应状态为STARTED和RESUMED时,处于活跃状态。
//这里使用了一个比较,也就是状态在STARTED和STARTED之后时,就处于活跃状态。
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@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;
//调用ObserverWrapper的activeStateChanged,再调用dispatchingValue分发数据。
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
//观察者和被观察者解除绑定
mOwner.getLifecycle().removeObserver(this);
}
}
ObserverWrapper是LiveData的抽象内部类。
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
//抽象方法,判断是否处于活跃状态
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
//处于活跃状态,发送最新的值
dispatchingValue(this);
}
}
}
2.3 observeForever 无条件感知数据变化
在调用LiveData的observeForever方法时,没有传入被观察者,值传入了观察者,这就决定了调用observeForever之后无法根据Activity/Fragment的生命周期去判断合适感知数据,只能无条件的接收所有数据。这里用AlwaysActiveObserver对观察者进行了包装。
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
//判断是否是主线程
assertMainThread("observeForever");
//创建一个AlwaysActiveObserver对象,对Observer进行包装
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
//ObserverWrapper包装了AlwaysActiveObserver和Observer
//把Observer和AlwaysActiveObserver存入map
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;
}
//这里传入的mActive一直是true,所以消息一直能无条件回调给观察者
wrapper.activeStateChanged(true);
}
再看AlwaysActiveObserver,shouldBeActive固定返回true。所以在considerNotify方法中,一直能执行到observer.mObserver.onChanged((T) mData),把数据回调给观察者。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
3 流程图
根据上边的源码分析,画出以下流程图。
关注木水小站 (zhangmushui.cn)和公众号【木水Code】,及时获取更多技术干货。
网友评论