LiveData
定义
- 一种可观察的数据存储器类,直译为实时数据(是一个数据持有者,给源数据包装一层,源数据使用LiveData包装后,可以被observer观察,数据有更新时observer可感知);
- 具有生命周期感知能力,可确保 LiveData 仅更新处于活跃生命周期状态(STARTED、RESUMED)的应用组件观察者(observer);
特点
- 确保界面符合数据状态:当生命周期状态变化时,LiveData通知Observer,可以在observer中更新界面。
观察者可以在生命周期状态更改时刷新界面,而不是在每次数据变化时刷新界面。 - 不会发生内存泄漏: observer会在LifecycleOwner状态变为DESTROYED后自动remove;
- 不会因 Activity 停止而导致崩溃:如果LifecycleOwner生命周期处于非活跃状态,则它不会接收任何 LiveData事件;
- 不需要手动解除观察:能自动管理生命周期
- 数据始终保持最新状态:数据更新时 若LifecycleOwner为非活跃状态,那么会在变为活跃时接收最新数据;
LiveData的简单使用
class LiveDataActivity : AppCompatActivity() {
private lateinit var mMutableLiveData: MutableLiveData
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
//1.创建LiveData实例,指定源数据类型
mMutableLiveData = MutableLiveData()
//2. 创建Observer实例,实现onChanged()方法,用于接收源数据变化并刷新UI
val observer = Observer {
LjyLogUtil.d("mMutableLiveData.observe.onChanged:${it}")
}
//3 LiveData实例使用observe()方法添加观察者observer,并传入LifecycleOwner
mMutableLiveData.observe(this, observer)
//4 更改LiveData中的数据
//4.1 如果想要在LiveData对象分发给观察者之前对其中存储的值进行更改,可以使用Transformations.map()
val mapLiveData = Transformations.map(mMutableLiveData, Function {
it + "_LJY"
})
mapLiveData.observe(this, Observer {
LjyLogUtil.d("mapLiveData.observe.onChanged:${it}")
})
//4.2 Transformations.switchMap(),切换监听
val liveData0 = MutableLiveData()
val liveData1 = MutableLiveData()
val liveData2 = MutableLiveData()
val switchMapLiveData = Transformations.switchMap(liveData0, Function {
if (it) {
liveData1
} else {
liveData2
}
})
switchMapLiveData.observe(this, Observer {
LjyLogUtil.d("switchMapLiveData.observe.onChanged:${it}")
})
liveData1.value = "123"
liveData2.value = "456"
liveData0.value = false
//5. 合并多个LiveData数据源
//MediatorLiveData继承自mutableLiveData,它将多个LiveData数据源集合起来,一个组件监听多个LiveData数据变化的目的
val mediatorLiveData=MediatorLiveData()
mediatorLiveData.addSource(liveData0, Observer {
LjyLogUtil.d("mediatorLiveData.addSource(liveData0):$it")
})
mediatorLiveData.addSource(liveData1, Observer {
LjyLogUtil.d("mediatorLiveData.addSource(liveData1):$it")
})
mediatorLiveData.addSource(liveData2, Observer {
LjyLogUtil.d("mediatorLiveData.addSource(liveData2):$it")
})
mediatorLiveData.observe(this, Observer {
LjyLogUtil.d("mediatorLiveData.observe:$it")
})
liveData1.value = "321"
liveData2.value = "654"
//6. LiveData实例使用setValue()(主线程)/postValue()(子线程) 更新源数据
LjyLogUtil.d("onCreate")
mMutableLiveData.value = "value=onCreate"
GlobalScope.launch {
liveData0.postValue(true)
delay(2000)
mMutableLiveData.postValue("value=GlobalScope")
liveData0.postValue(false)
}
}
override fun onStart() {
super.onStart()
LjyLogUtil.d("onStart")
mMutableLiveData.value = "value=onStart"
}
override fun onResume() {
super.onResume()
LjyLogUtil.d("onResume")
mMutableLiveData.value = "value=onResume"
}
override fun onPause() {
super.onPause()
LjyLogUtil.d("onPause")
mMutableLiveData.value = "value=onPause"
}
override fun onStop() {
super.onStop()
LjyLogUtil.d("onStop")
mMutableLiveData.value = "value=onStop"
}
override fun onDestroy() {
super.onDestroy()
LjyLogUtil.d("onDestroy")
mMutableLiveData.value = "value=onDestroy"
}
}
- 上面的更新数据源方法setValue()(主线程)/postValue()(子线程),主要是为了区分调用场景,其代码如下
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
//postValue方法把Runable对象mPostValueRunnable抛到主线程,其run方法中还是使用的setValue()
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue); //也是走到setValue方法
}
};
拓展LiveData对象
//1. 自定义LiveData
class MyLiveData(context: Context) : LiveData() {
init {
LocationUtil.getInstance().getLocation(context)
}
companion object {
var instance: MyLiveData? = null
fun get(context: Context): MyLiveData? {
if (instance == null) {
instance = MyLiveData(context)
}
return instance
}
}
val callback = LocationUtil.CallBack() {
//注意这里的value(setValue)对应使用时的observe
value = it
}
override fun onActive() {
super.onActive()
LjyLogUtil.d("MyLiveData.onActive")
LocationUtil.getInstance().setCallBack(callback)
}
override fun onInactive() {
super.onInactive()
LjyLogUtil.d("MyLiveData.onInactive")
LocationUtil.getInstance().removeCallBack()
}
}
//2. 使用:
MyLiveData.get(this)?.observe(this, Observer {
LjyLogUtil.d("LiveDataActivity:$it")
})
- 当LiveData对象具有Active状态的观察者时调用onActive方法,才会有监听(setCallBack),当LiveData对象没有任何Active状态的观察者时调用onInactive方法,会移除监听(removeCallBack),callBack的onCall()中绑定了数据value = it,所以observe()可以观察到实时数据;
LiveData原理
- 经过上面的使用我们发现LiveData和RxJava很相似,都是用的观察者模式,不同的是LiveData不是通知所有的观察者,而是只通知Active状态的观察者,那么这是如何做到的呢?
LiveData观察组件生命周期
- 我们知道LiveData是通过observe()来注册观察者,那么以此为入口来看看其代码是如何实现的
- 从observe()的第二行可以看到判断了getCurrentState() == DESTROYED则return,说明如果组件为DESTROYED状态是不允许注册为观察者的
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//owner, observer的包装类
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//将observer和LifecycleBoundObserver存储到SafeIterableMap, ObserverWrapper>
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
//不能添加同一个observer却不同LifecycleOwner
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
//当前owner已经添加过了则return
if (existing != null) {
return;
}
//将LifecycleBoundObserver添加到Lifecycle中完成注册
owner.getLifecycle().addObserver(wrapper);
}
// 除了使用observe()方法添加观察者,也可以使用observeForever(Observer) 方法来注册
// 未关联 LifecycleOwner的观察者。在这种情况下,观察者会被视为始终处于活跃状态;
@MainThread
public void observeForever(@NonNull Observer super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
- 再来看看LifecycleBoundObserver,它是LiveData的内部类
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer super T> observer) {
super(observer);
mOwner = owner;
}
//判断当前传入的组件的状态是否是Active (STARTED和RESUMED状态)
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//组件状态发生变化时,会调用onStateChanged方法
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
//DESTROYED状态时,移除observer
removeObserver(mObserver);
return;
}
//调用父类的方法
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
- 上面组件状态发生变化时,会调用onStateChanged(),onStateChanged中调用了父类的activeStateChanged(),其代码如下,可以看到activeStateChanged会根据Active状态和处于Active状态的组件的数量,来对onActive方法和onInactive方法回调,这两个方法用于拓展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;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
}
- 上面代码的最后,如果是Active状态,会调用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, 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;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
- 可以看到如果条件都满足会调用Observer的onChanged方法,这个方法正是使用LiveData的observe方法的回调
阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/19312,转载请注明出处。
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/19312,转载请注明出处。
评论0