object MyLiveData {
val info1: MutableLiveData<String> by lazy { MutableLiveData<String>() }
}
class LiveDataActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
val textview: TextView = findViewById(R.id.livedata_textview)
// 1 activity 是观察者
MyLiveData.info1.observe(this) {
textview.text = it
}
// 完整写法 new Observer onChanged
// MyLiveData.info1.observe(this, object : Observer{
// override fun onChanged(value: String) {
// println("activity 2 收到消息:$value")
// }
// })
// 2 触发数据改变
MyLiveData.info1.value = "default" // setValue 主线程
thread {
Thread.sleep(3000)
MyLiveData.info1.postValue("3 秒钟后,修改了哦") // postValue 子线程
}
thread {
Thread.sleep(6000)
MyLiveData.info1.postValue("6 秒钟后,修改了哦") // postValue 子线程
}
}
}
(1)观察者管理
我们都是调用 LiveData.observe 方法观察数据的变化。
MyLiveData.info1.observe(this, object : Observer<String>{
override fun onChanged(value: String) {
println("activity 2 收到消息:$value")
}
})
从 observe 函数入手,看它的逻辑。
// LiveData.java
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 代码1
assertMainThread("observe");
// 代码2 检查生命周期状态
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 代码3 将观察者包装为 LifecycleBoundObserver
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;
}
// 代码4 将观察者与生命周期绑定
owner.getLifecycle().addObserver(wrapper);
}
observe函数的第一个参数 LifecycleOwner,属于被观察者。Fragment或Activity的父类都继承了 LifecycleOwner 接口,而 LifecycleOwner 可获取到组件的 Lifecycle。所以 LiveData 通过 observe() 方法将观察者与组件的生命周期绑定了。
代码1:observe() 方法要求必须是在主线程调用。
代码2:接着判断当前是否是销毁状态,如果是就直接 return。
代码3:创建一个 LifecycleBoundObserver 对象,它是 ObserverWrapper 子类,可以感知宿主的生命周期。
调用 mObservers.putIfAbsent(observer, wrapper) 将 observe 和 wrapper 分别作为 key 和 value 存入 Map 中,putIfAbsent()方法会判断如果 value 已经能够存在,就返回,否则返回null。 如果返回existing为null,说明以前没有添加过这个观察者,就将LifecycleBoundObserver 作为宿主生命周期的观察者。
代码4:将观察者与生命周期绑定
(2)生命周期感知
接着看一下 LifecycleBoundObserver 逻辑:
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
// 代码1 判断当前状态是否是存活状态STARTED,RESUMED。
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
// 代码2 宿主每个生命周期执行时回调的函数
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
// 代码3 如果当前状态是DESTORYED,会解除所有观察者
if (currentState == DESTROYED) {
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
// 代码4 判断当前状态和上个状态是否一致,不一致的话调用 activeStateChanged(shouldBeActive())
while (prevState != currentState) {
prevState = currentState;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
void activeStateChanged(boolean newActive) {
// 代码5
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
// 代码6
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
// 代码7
dispatchingValue(this);
}
}
代码1,判断当前状态是否是存活状态STARTED,RESUMED。
代码2,宿主每个生命周期执行时回调的函数。
在分析 Lifecycle 源码时,我们看到过 LifecycleRegistry 中的同步方法 sync() 中,backwardPass 和 forwardPass,都调用了 observer.dispatchEvent() 分发生命周期事件。也就是说每个生命周期事件都会触发dispatchEvent(),然后调用 mLifecycleObserver.onStateChanged(owner, event),这里就会触发 LiveData 的 LifecycleBoundObserver 中 onStateChanged()。
代码3,每个生命周期回调到这里都会判断当前的状态是否 DESTROYED,如果是就移除所有的观察者,并return。
代码4,否则,判断当前状态和上个状态是否一致,不一致的话调用 activeStateChange(shouldBeActive()),然后调用changeActiveCounter(mActive)。
代码5,判断组件状态是否发生了变化。如果发生了变化,接着判断 mActive 状态。
代码6,当mActive是true时,会调用onActive()空函数,由外界实现。是false时,会调用onInactive()空函数,由外界实现。
代码7,做完这些之后,当 mActive 存活时,会继续执行 dispatchingValue(initiator),进行数据分发,后面再继续看。
(3)数据存储与更新
看完了观察者的逻辑之后,我们接着看LiveData 是怎么通知观察者的?
private volatile Object mData;
setValue()
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++; // 数据版本号增加
mData = value;
dispatchingValue(null); // 通知观察者
}
setValue() 必须在主线程调用,先进行版本号加1,然后调用 dispatchingValue(null) 方法。
postValue()
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
postValue() ,可以在后台线程调用,通过Handler从子线程切换到主线程后,再调用 setValue()。
(4)数据分发
了解了数据更新触发的逻辑后,接着看数据分发通过 dispatchingValue() 方法的实现:
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// 代码1
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
// 代码2 遍历观察者
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
private void considerNotify(ObserverWrapper observer) {
// 代码3 检测当前状态是否是活跃状态
if (!observer.mActive) {
return;
}
// 代码4 再次循环检测当前是否存活,不存活就等待。可以检测当前页面突然可见的状况。
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 代码5 下面是粘性事件。判断观察者的版本和被观察者的版本,如果被观察者的版本小于观察者,就走onChange(mData)分发数据。
// 去除粘性:反射修改mLastVersion 让相等,直接return,不走后面dispatch
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
// 代码6
observer.mObserver.onChanged((T) mData);
}
代码1,dispatchingValue() 参数传 null 和不传 null 的区别是,如果传null,会通知所有的观察者。否则,只会通知传入的观察者。
代码2,遍历所有的观察者,也就是我们上面说的 LifecycleBoundObserver,调用 considerNotify() 方法。
代码3,检测当前状态是否是活跃状态。
代码4,再次循环检测当前是否存活,不存活就等待。可以检测当前页面突然可见的状况。
代码5,是粘性事件。判断观察者的版本和被观察者的版本,如果被观察者的版本小于观察者,就走onChange(mData)分发数据。
去除粘性:反射修改mLastVersion 让相等,直接return,不走后面dispatch。
代码6,observer.mObserver 是我们调用 LiveData 的 observe 方法传入的 Observer,然后调用 onChange(value) ,将更新的数据回调给我们自己的 onChange 中,实现了数据的更新。
class UnPeekLiveData<T> : MutableLiveData<T>() {
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)
hook(observer)
}
private fun hook(observer: Observer<in T>) {
val liveDataClass = LiveData::class.java
try {
//获取field private SafeIterableMap, ObserverWrapper> mObservers
val mObservers = liveDataClass.getDeclaredField("mObservers")
mObservers.isAccessible = true
//获取SafeIterableMap集合mObservers
val observers = mObservers[this]
val observersClass: Class<*> = observers.javaClass
//获取SafeIterableMap的get(Object obj)方法
val methodGet = observersClass.getDeclaredMethod("get", Any::class.java)
methodGet.isAccessible = true
//获取到observer在集合中对应的ObserverWrapper对象
val objectWrapperEntry = methodGet.invoke(observers, observer)
var objectWrapper: Any? = null
if (objectWrapperEntry is Map.Entry<*, *>) {
objectWrapper = objectWrapperEntry.value
}
if (objectWrapper == null) {
throw NullPointerException("ObserverWrapper can not be null")
}
//获取ObserverWrapper的Class对象 LifecycleBoundObserver extends ObserverWrapper
val wrapperClass: Class<*>? = objectWrapper.javaClass.superclass
//获取ObserverWrapper的field mLastVersion
val mLastVersion = wrapperClass!!.getDeclaredField("mLastVersion")
mLastVersion.isAccessible = true
//获取liveData的field mVersion
val mVersion = liveDataClass.getDeclaredField("mVersion")
mVersion.isAccessible = true
val mV = mVersion[this]
//把当前ListData的mVersion赋值给 ObserverWrapper的field mLastVersion
mLastVersion[objectWrapper] = mV
mObservers.isAccessible = false
methodGet.isAccessible = false
mLastVersion.isAccessible = false
mVersion.isAccessible = false
} catch (e: Exception) {
e.printStackTrace()
}
}
}
通常,MutableLiveData 用于 ViewModel 中,而 LiveData 暴露给 UI 层,以确保数据的安全性。
如果需要从后台线程更新 LiveData,应该使用 postValue()。
(1)LiveData:
(2)RxJava:
选择依据:如果只是简单的 UI 更新,LiveData 更合适;如果需要复杂的异步操作,RxJava 更强大。
如:
val userLiveData: LiveData<User> = ...
val userNameLiveData: LiveData<String> = Transformations.map(userLiveData) { user ->
user.name
}
如:
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getUsers(): LiveData<List<User>>
}
(1)LiveData:
(2)StateFlow:
是 Kotlin Flow 的一部分,功能更强大。
需要手动管理生命周期,但可以与协程无缝集成。
选择依据:如果项目已经使用协程,StateFlow 是更好的选择;否则,LiveData 更简单易用。
如:
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> get() = _data
fun updateData(newValue: String) {
_data.value = newValue
}
}
observe() 在源码分析时,我们已经看过了。
接下来看一下 observeForever()
@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);
}
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);
}
}
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
可以发现观察者的封装是 AlwaysActiveObserver,在 AlwaysActiveObserver 中 shouldBeActive() 永远返回的是 true。无论生命周期状态如何,都会收到更新。
可以通过将 LiveData 定义在 ViewModel 中,并在多个 Fragment 或 Activity 之间共享同一个 ViewModel 实例。
如:ShareViewModel
val viewModel = ViewModelProvider(activity).get(SharedViewModel::class.java)
viewModel.sharedData.observe(this, Observer { data ->
// 更新 UI
})
LiveData 通过以下机制保证线程安全: