LiveData的使用会结合Lifecycles和ViewModel一起使用,不了解二者的,建议先看这两篇文章:
Android Jetpack之ViewModel源码分析
Android Jetpack之Lifecycles源码分析
LiveData 是保存数据对象的类,通过注册监听器Observer 监听数据的变化。LiveData最大的优势:LiveData 是感知Activity、Fragment等生命周期的组件,Observer 可以指定监听的生命周期(Lifecycle)对象。当 Observer 的 Lifecycle 对象处于 STARTED 或者 RESUMED 状态的时候, LiveData 处于活动状态,在活动状态下数据变化会通知到相应的Observer。当相应Lifecycle对象的状态改变为DESTROYED时移除观察者,所以避免造成内存泄漏。当然也可以不和Lifecycles绑定,使用observeForever(Observer)方法注册一个没有关联生命周期所有者对象的观察者,观察者总是处于活动状态,因此数据变化事件总是会被通知到,可以通过调用removeObserver(Observer) 删除observer。
官网指导链接Android jetpack之LiveData
创建一个ViewModel类,里面有LiveData实例来保存数据。使用ViewModel是为了在屏幕旋转等操作下时可以恢复现场数据。
class MyLiveDataViewModel : ViewModel(){
var liveData: MutableLiveData?= null
get() {
if(field == null){
field = MutableLiveData()
}
return field
}
}
(1)代码1: 创建LiveDataActivity实现LifecycleOwner接口,为了Observer和组件的生命周期绑定。
(2)代码2: 获取定义的MyLiveDataViewModel实例
(3)代码3: 创建定义onChanged()方法的Observer对象,在数据变化时更新UI页面。
(4)代码4: LiveData订阅观察,将LiveData和Lifecycles、Observer绑定,
(5)代码5: LiveData设置新数据,通知观察者更新数据。可以在子线程中执行。
完整代码如下:
//代码1
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
private lateinit var lifecycleRegistroy: LifecycleRegistry
private var coun : Int by Delegates.notNull()
override fun getLifecycle(): Lifecycle {
return lifecycleRegistroy
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
lifecycleRegistroy = LifecycleRegistry(this)
coun = 0
//代码2
var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
//代码3
val observer = Observer{
text.text = it
}
button.setOnClickListener {
//代码5
viewModel.liveData?.postValue("changed !!!!"+coun++)}
//代码4
viewModel.liveData?.observe(this,observer)
}
}
在Activity中通过添加observe方法将Lifecycles和Observer绑定起来。下面我们来分析该方法。该方法有两个参数:
下面来分析observe方法内部的实现原理:
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);
}
通过observe.observer的分析我们知道,内部主要是用了LifecycleBoundObserver类,下面分析该类
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@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(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
LifecycleBoundObserver 继承自 ObserverWrapper并且在onStateChanged中调用了activeStateChanged的方法,下面来分析一下ObserverWrapper类。
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);
}
}
}
使用observeForever(Observer)方法注册一个没有关联生命周期所有者对象的观察者,观察者总是处于活动状态,因此数据变化事件总是会被通知到。下面我们来看一下其中的原理:
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);
}
在observeForever使用的AlwaysActiveObserver该类不同于LifecycleBoundObserver类,没有实现GenericLifecycleObserver接口,所以不能感激组件的生命周期变化,并且其实该方法,也没有LifecycleOwner的形参。在AlwaysActiveObserver 的类内部的shouldBeActive方法用于返回ture,并且在observeForever内部将ObserverWrapper.mActive设置为true,也就是标明永远是处于活跃状态,所以Observer是一直可以观察数据变化的。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
在Activity中,通过postValue或者setValue改变LivwData的数据,在通过Observer,观察LIveData数据的变化。通过上面的分析,我们已经知道了Observer是如何和组件的生命周期绑定起来的,下面我们就分析一下,LiveData的数据更新是如何通知到Observer 的。
先来分析一下setValue()方法,setValue()必须在主线程中调用,否则会报错,而postValue则没有这个检查。看到有无post的区别,第一反应就是是invalidate和postInvalidate的区别。
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
下面在分析一下dispatchingValue方法。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//代码1
for (Iterator, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
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;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
postValue方法可以在非主线程中更新数据。主要是通过ArchTaskExecutor和DefaultTaskExecutor切换到主线程中。然后回调到Runnable方法中,在Runnable的run方法其实也是调用了setValue方法来实现通知观察者更新数据的逻辑的。
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
ArchTaskExecutor是单例模式。继承自TaskExecutor。
public static ArchTaskExecutor getInstance() {
if (sInstance != null) {
return sInstance;
}
synchronized (ArchTaskExecutor.class) {
if (sInstance == null) {
sInstance = new ArchTaskExecutor();
}
}
return sInstance;
}
当调用postToMainThread切换线程是,内部实际上是执行了DefaultTaskExecutor类的postToMainThread方法。
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
DefaultTaskExecutor类的postToMainThread内部通过Handler实现线程的切换。
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
LiveData 支持简单的数据变换。
使用 Transformation 的好处:如果 Lifecycle 处于未激活状态,则转换函数也同样不会执行。
map实例:
class MyLiveDataViewModel : ViewModel(){
var liveData: MutableLiveData = MutableLiveData()
get() {
return field
}
}
class User(val name: String,val lastName: String)
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
private lateinit var lifecycleRegistroy: LifecycleRegistry
override fun getLifecycle(): Lifecycle {
return lifecycleRegistroy
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
lifecycleRegistroy = LifecycleRegistry(this)
var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
val observer = Observer{
text.text = it
}
button.setOnClickListener {
var user = User("android","jectpack")
viewModel.liveData.postValue(user)}
val userLivaData: LiveData = viewModel.liveData
val nameLiveData: LiveData = Transformations.map(userLivaData){
it.name + it.lastName
}
nameLiveData.observe(this,observer)
}
}
switchMap实例:
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
private lateinit var lifecycleRegistroy: LifecycleRegistry
override fun getLifecycle(): Lifecycle {
return lifecycleRegistroy
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
lifecycleRegistroy = LifecycleRegistry(this)
var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
val observer = Observer{
text.text = it
}
button.setOnClickListener {
var user = User("android","jectpack")
viewModel.liveData.postValue(user)}
val userLivaData: LiveData = viewModel.liveData
val nameLiveData: LiveData = Transformations.switchMap(userLivaData){
getUserName(it)
}
nameLiveData.observe(this,observer)
}
private fun getUserName(user: User): LiveData {
val liveData: MutableLiveData = MutableLiveData()
liveData.value = user.name +" switch map " + user.lastName
return liveData
}
}
MediatorLiveData的作用是合并几个流到一个流中。
实例代码:
class LiveDataActivity : AppCompatActivity(),LifecycleOwner{
private lateinit var lifecycleRegistroy: LifecycleRegistry
override fun getLifecycle(): Lifecycle {
return lifecycleRegistroy
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
lifecycleRegistroy = LifecycleRegistry(this)
var viewModel = ViewModelProviders.of(this).get(MyLiveDataViewModel::class.java)
val observer = Observer{
text.text = it
}
button.setOnClickListener {
var user = User("android","jectpack")
viewModel.liveData.postValue(user)}
val userLivaData: LiveData = viewModel.liveData
val nameLiveData: LiveData = Transformations.switchMap(userLivaData){
getUserName(it)
}
var mediatorLiveData: MediatorLiveData = MediatorLiveData()
mediatorLiveData.addSource(userLivaData){
mediatorLiveData.value = "first source "
}
mediatorLiveData.addSource(nameLiveData){
mediatorLiveData.value = it + " second source"
}
mediatorLiveData.observe(this,observer)
}
private fun getUserName(user: User): LiveData {
val liveData: MutableLiveData = MutableLiveData()
liveData.value = " "
return liveData
}
}