})
val transformationsLiveData = Transformations.map(
mutableLiveData
) { input ->
(“$input go”)
}
transformationsLiveData.observe(this, Observer {
Log.d(TAG, “obChanged2: $it”)
})
mutableLiveData.postValue(1)
}
2.2.2 Transformations.switchMap 方法
和 map 不同, switchMap返回的结果必须是一个 LiveData
数据,而且它可以通过一个 Boolean 值来选择监听对象
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mutableLiveData1 = MutableLiveData()
mutableLiveData2 = MutableLiveData()
// 1
liveDataSwitch = MutableLiveData()
// 如果是true,选择监听1,否则监听2
val transformedLiveData = Transformations.switchMap(liveDataSwitch) {
if (it) mutableLiveData1 else mutableLiveData2
}
transformedLiveData.observe(this, Observer {
Log.d(TAG, “onChanged: $it”)
})
liveDataSwitch.postValue(false)
mutableLiveData1.postValue(“noel”)
mutableLiveData2.postValue(“bye”)
}
注释1:创建一个 MutableLiveData<Boolean>
来控制切换并复制给 liveDataSwitch
当 liveDataSwitch 的值为 true 时, 返回 mutableLiveData1, 否则返回 mutableLiveData2
这样最终输出的结果为2
2.2.3 MediatorLiveData合并数据源
MediatorLiveData
继承自 MutableLiveData, 它的作用是可以收集多个 LiveData。 如果其中一个 LiveData 数据源发生变化,那么也会通知到 MediatorLiveData
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val mutableLiveData1 = MutableLiveData()
val mutableLiveData2 = MutableLiveData()
// 创建一个用于合并数据源的LiveData
val liveDataManager = MediatorLiveData()
// 添加数据 LiveData1, 并监听其变化
liveDataManager.addSource(mutableLiveData1) {
Log.d(TAG, “onChanged 1: $it”)
}
// 添加数据 LiveData2, 并监听其变化
liveDataManager.addSource(mutableLiveData2) {
Log.d(TAG, “onChanged 2: $it”)
}
liveDataManager.observe(this, Observer {
Log.d(TAG, “onChanged Data: $it”)
})
mutableLiveData1.postValue(“i always like u”)
liveDataManager.postValue(“thank u”)
}
打印结果:
2.2.4 自定义LiveData
我们可以自定义一个 LiveData, 因为会有观察者来观察这个 LiveData, 所以观察者处于 STARTED 或者 RESUMED 时,LiveData 将会处于 Activity状态,这个时候通过实现 onActive()
/ onInactive()
来通知观察者。
下面是个例子,我们设定一个可以变化的数据类:
class ExtStringLiveData private constructor() : LiveData() {
companion object {
private const val TAG = “ExtStringLiveData”
private var sInstance: ExtStringLiveData? = null
@MainThread
fun get(): ExtStringLiveData? {
if (sInstance == null) {
sInstance = ExtStringLiveData()
}
return sInstance
}
}
// 观察者处于活跃状态, 则通知它
override fun onActive() {
Log.d(TAG, “onActive”)
// 这里的数据是写死的, 在实际项目中, 可以以监听器不断输出数据
value = “if u find me again, i will with u again”
}
override fun onInactive() {
Log.d(TAG, “onInactive”)
// 这里的数据是写死的, 在实际项目中, 可以以监听器不断输出数据
// 在这之后, 就不会再想观察者发送数据直到观察者恢复active状态, 所以这一里在更改数据就不会通知了
value = “because I’m starting to regret it”
}
}
然后在 MainActivity 去监听它:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
ExtStringLiveData.get()?.observe(this, Observer {
Log.d(TAG, it)
})
}
打印结果为:
而在 LiveData 的 onInactive()
中更改的string数据, MainActivity 就打印不出来了。
=======================================================================
因为组件都是通过调用 LiveData.observe(LifecycleOwner, Observer<? super T>)
进行监听,所以了解 Livecycle
的同学肯定就知道了其中的奥秘。我们来看看它的源码吧:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread(“observe”);
// 1
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
// 2
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 3
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);
}
注释1:如果当前声明周期是 DESTORYED
, 则拒绝注册
注释2:新建一个 LifecycleBoundObserver
实例,并传入相应参数
注释3:mObservers 的类型是 SafeIterableMap<Observer<? super T>, ObserverWrapper>mObservers
,key是观察者,value是注释2中创建的对象。
在这个map中的putIfAbsent
和 put
是有区别的,如果传入的 key 存在,就返回value,而不替换,如果 key 不存在,则添加进去,并返回null。
注释4:如果注释3的map中没有数据, 则调用 Lifecycle.addObserver
,传入的是 LivecycleBoundObserver
。 看来这个类比较重要,我们有必要去了解它的构造和作用。
来看看 LivecycleBoundObserver
,它是 LiveData 的内部类:
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull final LifecycleOwner mOwner;
…
@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;
// 1
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
该类继承了 ObserverWrapper
类,重写了 shouldBeActive()
方法, 它的作用是用来判断当前传入的组件是否是 Active的, Active状态包括 STARTED 、 RESUMED
该类还实现了 LifecycleEventObserver
接口,当组件状态发生变化的时候, 会调用 onStateChanged()
,当组件处于 DESTORYED 状态是,会调用 removeObserver()
来移除 observer。
这也就是为什么,LiveData 不会给那些 Inactive 的组件发通知。
注释1: 调用父类的 activeStateChanged()
,我们来看看父类:
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) {
// 1
dispatchingValue(this);
}
}
}
ObserverWrapper
是一个抽象类,它包装了一个 Observer, activeStateChanged
会看 传进来的状态是否和此前状态是否相同,不同则,则执行 changeActiveCounter()
,来更新一下当前LiveData 观察者的活跃与非活跃的数量, 来决定调用 onActive()
或 onInactive()
其次,如果当前是 Active 状态,则调用注释1的 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;
// 1
observer.mObserver.onChanged((T) mData);
}
即使是到了这里,也会一直在判断当前组件的状态,非常严格呢。
如果所有更新条件都满足,则会调用 Observer 的 onChanged()
, 也就从这里回调出去了~
我们来看看调用 postValue()
/ setValue()
之后,LiveData 做了什么事情, 这里以 postValue 为例,来看看代码~
protected void postValue(T value) {
boolean postTask;
最后
我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了5、6年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。
其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。
不断奔跑,你就知道学习的意义所在!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
)3.3 postValue 方法
我们来看看调用 postValue()
/ setValue()
之后,LiveData 做了什么事情, 这里以 postValue 为例,来看看代码~
protected void postValue(T value) {
boolean postTask;
最后
我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了5、6年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。
其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。
不断奔跑,你就知道学习的意义所在!
[外链图片转存中…(img-nHeYDAGL-1715782028295)]
[外链图片转存中…(img-kqgvBZNL-1715782028296)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!