https://blog.csdn.net/jhbxyz/article/details/108321239
先抛出大佬写的…写的确实好,但是我只是喜欢自己总结罢了
LiveData,也作为MVVM框架内基础的一员,可以很好的将我们的V层和VM层分开。那我们靠的就是LiveData.~那它具有的特性为:
使用 LiveData 具有以下优势:
确保界面符合数据状态
LiveData 遵循观察者模式。当生命周期状态发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面。
不会发生内存泄漏
观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。
不会因 Activity 停止而导致崩溃
如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
不再需要手动处理生命周期
界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
数据始终保持最新状态
如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
适当的配置更改
如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
共享资源
您可以使用单一实例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象。如需了解详情,请参阅扩展 LiveData。
那我们来根据源码一条条的解释为什么它可以具有那么多的特性.
总结下来为:
LiveData如何感知生命周期(不发生内存泄漏)?
为何观察者生命周期非活跃状态,不接受LiveData事件?
为何数据始终保持最新状态?
我们的初始就位对LiveData直接进行observe。
viewmodel.demo.observe(viewLifecycleOwner, Observer {
val text = StringBuilder(it+" ")
binding.StoryWifiLittleText.text = text
})
随着我们轻轻的步伐柔柔的进来(Last Dance).~
先不要在意太多.我们映入眼帘的是owner.getLifecycle().addObserver(wrapper);
可以看到, 这里仍然是使用LifeCycle添加了生命周期的感应.
observer被LifecycleBoundObserver 所封装加入到Lifecycle中
@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);
}
所以,我们解决了第一个问题。
如何感知生命周期–>Lifecycle干的。
但是具体感知到什么生命周期去做什么,我们这里先留下来。先不管(其实就是LifecycleBoundObserver类)
我们要探究为何只通知活跃的观察者,我们就去看我们的setvalue方法.
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
小知识:
可以看到mVersion++.为版本号,这里就导致出现一个粘性事件了(发送早于注册,仍然可以接受到信息的通知)。是因为这里的mVersion++已经被改变了,所以一定会发送消息
进入到我们的dispatchingValue
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;
observer.mObserver.onChanged((T) mData);
}
可以看到在发送调用onChanged之前,会去先判断observer是否为活跃的状态.
observer.shouldBeActive()
observer类又是我们熟悉的ObserverWrapper
,所以此时我们要回头看回来我们的LifecycleBoundObserver
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() {
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;
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
看到,类继承了LifecycleEventObserver接口,且在这类中重写了shouldBeActivty,onStateChanged方法.
shouldBeActivty,判断观察者是否为活跃状态
而return则是生命周期大于STARTED才会返回true.
这里就回答了我们第二个问题
在观察者为非活跃状态时,是不会调用其通知的
我们继续看,onStateChanged,在生命周期发生变化时,会调用该函数
看看它做的事情,在生命周期为DESTORYED时,移除了观察者.符合其特性.
然后还调用了 activeStateChanged(shouldBeActive());
我们往内看一下。
private abstract class ObserverWrapper {
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);
}
}
}
我们发现,他是继承的ObserverWrapper方法.里面在有dispatchingValue
方法.
这不就真相大名了吗?dispatchingValue就是我们上面setValue时会调用的方法.
这也就解决了我们的第三个问题
保留最新的数据就是因为在Observer时,它在生命周期变动中,也一样会dispatchingValue到我们的observer上~
我们的viewmodel和livedata都是同时使用的,而里面都十分关注于我们的Lifecycle.那就说明这个感知生命周期的组件很重要,需要我们更多的关注喔…
关注源码~学习更Nice…
OS:Android要学的东西好多啊…为什么还要问那么多…慢慢来吧,人前的靓丽都是时间背后的积累~加油