Android Jetpack系列–2.LiveData使用及源码解析

LiveData

定义

  • 一种可观察的数据存储器类,直译为实时数据(是一个数据持有者,给源数据包装一层,源数据使用LiveData包装后,可以被observer观察,数据有更新时observer可感知);
  • 具有生命周期感知能力,可确保 LiveData 仅更新处于活跃生命周期状态(STARTED、RESUMED)的应用组件观察者(observer);

特点

  1. 确保界面符合数据状态:当生命周期状态变化时,LiveData通知Observer,可以在observer中更新界面。
    观察者可以在生命周期状态更改时刷新界面,而不是在每次数据变化时刷新界面。
  2. 不会发生内存泄漏: observer会在LifecycleOwner状态变为DESTROYED后自动remove;
  3. 不会因 Activity 停止而导致崩溃:如果LifecycleOwner生命周期处于非活跃状态,则它不会接收任何 LiveData事件;
  4. 不需要手动解除观察:能自动管理生命周期
  5. 数据始终保持最新状态:数据更新时 若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,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?