关于LiveData的介绍可以看我上一篇文章
Android LiveData笔记
LiveData使用
首先创建MutableLiveData<T>对象,然后设置观察者,观察者有两种设置模式一种是
//关联宿主生命周期,宿主销毁后会自动取消观察者
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
//不关联宿主生命周期,宿主销毁不会取消观察者
public void observeForever(@NonNull Observer<? super T> observer)
例子使用的是第一种方式注册观察者
/**
* 主线程上发送消息可以使用postValue, setValue
* 子线程上发送消息必须使用postValue
* 不论在哪个线程上,接受消息都在主线程上
*/
class LiveDataTestActivity : AppCompatActivity(){
private val TAG = "LiveDataTestActivity";
val mutableLiveData : MutableLiveData<String> = MutableLiveData()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.frament_test)
mutableLiveData.observe(this, Observer {
Log.e(TAG, "onCreate$it")
})
sendMsgInOnCreate()
mutableLiveData.observe(this, Observer {
Log.e(TAG, "onCreateAfterSend$it")
})
}
override fun onResume() {
super.onResume()
mutableLiveData.observe(this, Observer {
Log.e(TAG, "onResume$it")
})
}
fun sendMsgInOnCreate(){
mutableLiveData.value = "SUCCESS--${Thread.currentThread().name}"
mutableLiveData.value = "2SUCCESS--${Thread.currentThread().name}"
mutableLiveData.value = "3SUCCESS--${Thread.currentThread().name}"
}
}
在例子中,使用mutableLiveData对象在onCreate中发送了三条消息,在发送消息前后都注册了观察者。在onResum中也注册了观察,根据我的猜想打印的日志应该如下
E/LiveDataTestActivity: onCreateSUCCESS--main
E/LiveDataTestActivity: onCreate2SUCCESS--main
E/LiveDataTestActivity: onCreate3SUCCESS--main
E/LiveDataTestActivity: onCreateAfterSend3SUCCESS--main
E/LiveDataTestActivity: onResume3SUCCESS--main
但事实上输入的日志却是
E/LiveDataTestActivity: onCreate3SUCCESS--main
E/LiveDataTestActivity: onCreateAfterSend3SUCCESS--main
E/LiveDataTestActivity: onResume3SUCCESS--main
这是因为LiveData只会通知活跃状态的观察者。
/**
* Started state for a LifecycleOwner. For an {@link android.app.Activity}, this state
* is reached in two cases:
* <ul>
* <li>after {@link android.app.Activity#onStart() onStart} call;
* <li><b>right before</b> {@link android.app.Activity#onPause() onPause} call.
* </ul>
*/
STARTED,
在Lifecycle中onStart状态时在onStart方法调用后,onPause方法调用前被修改的
宿主生命状态必须为onStart状态观察者才会是活跃状态,所以在onCreate或者onResume()中注册的观察者并不会进入活跃状态,当生命周期进入onStart时三个观察者才会接受到消息,此时消息已经发送过了,所以三个观察者才会接受最后一条最新的消息。
如果将消息的发送放到onResume中,则三个观察者都会收到三条消息
override fun onResume() {
super.onResume()
mutableLiveData.observe(this, Observer {
Log.e(TAG, "onResume$it")
})
sendMsgInOnCreate()
}
E/LiveDataTestActivity: onCreateSUCCESS--main
E/LiveDataTestActivity: onCreateAfterSendSUCCESS--main
onResumeSUCCESS--main
E/LiveDataTestActivity: onCreate2SUCCESS--main
onCreateAfterSend2SUCCESS--main
E/LiveDataTestActivity: onResume2SUCCESS--main
onCreate3SUCCESS--main
E/LiveDataTestActivity: onCreateAfterSend3SUCCESS--main
onResume3SUCCESS--main
public static <X, Y> LiveData<Y> map( @NonNull LiveData<X> source, @NonNull final Function<X, Y> mapFunction)
Transformations.map方法是将LiveData的观察数据对象转换类型
val mutableLiveData3 : MutableLiveData<String> = MutableLiveData()
/**
* liveData的数据转换
*/
val liveDataMap :LiveData<Int> = Transformations.map(mutableLiveData3
) {
1
}
liveDataMap.observe(this, Observer {
Log.e(TAG, "liveDataMap$it")
})
mutableLiveData3.value = "liveDataMap";
E/LiveDataTestActivity: liveDataMap1
MediatorLiveData<String>是将多个观察者放到一起统一观察
mediatorLiveData.addSource(mutableLiveData1, Observer {
//数据源1有变换通知观察者更新
mediatorLiveData.value = it
})
mediatorLiveData.addSource(mutableLiveData2, Observer {
//数据源2有变换通知观察者更新
mediatorLiveData.value = it
})
mediatorLiveData.observe(this, Observer {
Log.e(TAG, "$it---${Thread.currentThread()}")
})
mutableLiveData1.value = "mutableLiveData1"
mutableLiveData2.value = "mutableLiveData2"
E/LiveDataTestActivity: mutableLiveData1---Thread[main,5,main]
E/LiveDataTestActivity: mutableLiveData2---Thread[main,5,main]
MediatorLiveData源码
@MainThread
public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) {
Source<S> e = new Source<>(source, onChanged);
Source<?> existing = mSources.putIfAbsent(source, e);
if (existing != null && existing.mObserver != onChanged) {
throw new IllegalArgumentException(
"This source was already added with the different observer");
}
if (existing != null) {
return;
}
if (hasActiveObservers()) {
e.plug();
}
}
private static class Source<V> implements Observer<V> {
final LiveData<V> mLiveData;
final Observer<? super V> mObserver;
int mVersion = START_VERSION;
Source(LiveData<V> liveData, final Observer<? super V> observer) {
mLiveData = liveData;
mObserver = observer;
}
void plug() {
mLiveData.observeForever(this);
}
void unplug() {
mLiveData.removeObserver(this);
}
@Override
public void onChanged(@Nullable V v) {
if (mVersion != mLiveData.getVersion()) {
mVersion = mLiveData.getVersion();
mObserver.onChanged(v);
}
}
}
在调用addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged)方法后,先将liveData 和传入的观察者包装成Source对象,接着调用Source对象的plug方法将传入的LiveData对象观察Source对象,在我们调用mutableLiveData1.value = "mutableLiveData1"对象时会出触发Source对象的onChanged方法,(前面分析LiveData的时候说过)在onChanged方法中会调用Source对象的mObserver.onChanged(v);方法也就是我们传入的
mediatorLiveData.addSource(mutableLiveData1, Observer {
//数据源1有变换通知观察者更新
mediatorLiveData.value = it
})
我们传入的Observer中调用mediatorLiveData的setValue就会通知到注册在mediatorLiveData上的观察者。(有点绕)
网友评论