LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 activity、fragment 或 service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。
您可以注册与实现 LifecycleOwner 接口的对象配对的观察者。有了这种关系,当相应的 Lifecycle 对象的状态变为 DESTROYED 时,便可移除此观察者。这对于 activity 和 fragment 特别有用,因为它们可以放心地观察 LiveData 对象,而不必担心泄露(当 activity 和 fragment 的生命周期被销毁时,系统会立即退订它们)。
LiveData 的优势:
以上内容均来自官网,官网地址
通过之前的博客:LiveData的简单使用。我们了解了LiveData的基本使用。这里回顾一下
LiveData的简单实用(一般都是跟ViewModel一起实用)
public class LiveDataActivity extends AppCompatActivity {private TextView mTextContent;//使用LiveDataprivate MutableLiveData contentLiveData = new MutableLiveData<>();@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_livedata_test);mTextContent = findViewById(R.id.tv_content);//设置 观察者contentLiveData.observe(this, new Observer() {@Overridepublic void onChanged(String s) {mTextContent.setText(s);}});//点击按钮,改变内容findViewById(R.id.btn_livedata_change).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {contentLiveData.setValue("内容改变了");}});}
}
下面的源码分析中,有些情况会设计到Lifecycle()监控生命周期。有兴趣的可以看下:Android Jetpack之Lifecycle的使用及源码分析
下面,我们通过上面使用的步骤,来分析。LiveData内容都做了什么操作
添加观察者,并且我们无需关系,移除及内存泄露问题
下面看下源码
private SafeIterableMap, ObserverWrapper> mObservers =new SafeIterableMap<>();...@MainThreadpublic void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {assertMainThread("observe");//owner是Activity已经实现的(Lifecycle文章有说)//如果owner的生命周期已经结束的话,直接返回。避免了内存泄露,甚至Crashif (owner.getLifecycle().getCurrentState() == DESTROYED) {// ignorereturn;}//wrapper包装类。里面主要是一些生命周期及版本的判断LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//这里,我们看到添加观察者的时候。是把观察者做key,放到了一个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;}//这里跟我们添加Lifecycle()一样,可以让wrapper监听owner生命周期,做一些判断owner.getLifecycle().addObserver(wrapper);}
看到这里,其实发现很简单,添加观察者,其实,就是在LiveData里面创建了一个Map,把观察者存进去。
Map的值是个包含了owner(这里就是Activity,方便理解)和观察者observer的封装类。
下面,我们看看LiveData的setValue()方法,是怎么把值传递过去的
public class MutableLiveData extends LiveData {@Overridepublic void setValue(T value) {super.setValue(value);}
}
这里调用了super.setValue()继续看
@MainThreadprotected void setValue(T value) {assertMainThread("setValue");//这里的版本,后面会说mVersion++;mData = value;dispatchingValue(null);}
这里做了2个事情:
1,把值赋值给mData
2,调用 dispatchingValue(null);
我们接着看下
void dispatchingValue(@Nullable ObserverWrapper initiator) {if (mDispatchingValue) {mDispatchInvalidated = true;return;}mDispatchingValue = true;do {mDispatchInvalidated = false;//initiator这里通过上面知道,传递的是null。所以,走elseif (initiator != null) {considerNotify(initiator);initiator = null;} else {//把所有观察者的Map,通过迭代器遍历for (Iterator, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue = false;}
这里,我们可以看到,dispatchingValue()方法就是,遍历观察者所在的Map,然后,调用considerNotify()方法。
看下considerNotify()方法
private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.//// we still first check observer.active to keep it as the entrance for events. So even if// the observer moved to an active state, if we've not received that event, we better not// notify for a more predictable notification order.if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//通过上面一系列的判断,最终调用了观察者的onChanged方法。observer.mObserver.onChanged((T) mData);}
这里,我们可以看到通过一些列生命周期的判断,版本的判断,最终调用了观察者的onChange()方法。
到这里,我们就已经走通了,所有的调用流程。
postValue的全过程跟setValue类似。只不过是后面通过Handler切换到了主线程上
[未完成]
上面有一点东西,我们没有说,那就是观察者observer的mLastVersion跟数据的mVersion问题。这个也是造成粘性数据的原因。但是,它跟EventBus不同的是,EventBus是提供了粘性数据的开关,但是,它并没有。
问题:LiveData的数据倒灌/粘性数据问题。
场景:(列表–详情(修改数据)–返回并点击其它列表–再次进入详情)(使用ShareViewModel)
SingleLiveEvent(解决一次事件,只消费一次),当注册多个观察者后,只有一个会受到,非常容易出错。
UnPeek-LiveData 解决方案
上一篇:谁知道VMD是什么
下一篇:形容亲人去世的悲伤的句子