注意:一般情况下,LiveData要配合ViewModel一起使用的,但是今天是单独使用LiveData,作为学习的话,我们可以只关注LiveData了。
LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

MyLiveData.kt
- object MyLiveData {
- // 这里为info1的MutableLiveData 懒加载初始化(懒加载:用到时才加载)
- val info1 : MutableLiveData
by lazy { MutableLiveData() } - init {
- info1.value = "default"
- }
- }
MainActivity.kt
- class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- val textView: TextView = findViewById(R.id.tv_textview)
- activity_main.xml
- // 1.观察者 眼睛 环节
- MyLiveData.info1.observe(this, {
- textView.text = it
- })
- // 2.触发数据 环节
- MyLiveData.info1.value = "default"
- thread {
- Thread.sleep(3000)
- MyLiveData.info1.postValue("三秒钟后,修改了哦")
- }
- thread {
- Thread.sleep(6000)
- MyLiveData.info1.postValue("六秒钟后,修改了哦")
- }
- // -------------- 下面是 触发修改数据 的写法
- // lambda 写法如下 observe:
- MyLiveData.info1.observe(this, {
- })
- // lambda 写法如下 observeForever:
- MyLiveData.info1.observeForever({
- })
- // 详细写法如下 observe:
- MyLiveData.info1.observe(this, object : Observer
{ - override fun onChanged(t: String?) {
- }
- })
- // 详细写法如下 observeForever:
- MyLiveData.info1.observeForever(object : Observer
{ - override fun onChanged(t: String?) {
- }
- })
- }
- }
MainActivity2.kt
- class MainActivity2 : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main2)
- val button = findViewById
- button.setOnClickListener {
- startService(Intent(this, MyService::class.java))
- Toast.makeText(MainActivity2@this, "推送服务器启动成功",
- Toast.LENGTH_SHORT).show()
- }
- MyLiveData.data1.observe(this, {
- Log.d("server", "界面可见,说明用户在查看微信列表界面啦,更新消息列表UI界
- 面:${it}")
- Toast.makeText(this, "更新消息列表UI界面成功:${it}",
- Toast.LENGTH_SHORT).show()
- })
- }
- }
MyLiveData.kt
- object MyLiveData {
- // 这里为info1的MutableLiveData 懒加载初始化(懒加载:用到时才加载)
- val data1: MutableLiveData
by lazy { MutableLiveData() } - // 注意:这里会奔溃 因为是在 thread { 首次实例化MyLiveData对象的,而下面确实setValue就会奔溃
- /*init {
- data1.value = "default"
- }*/
- }
MyService.kt
- class MyService : Service() {
- override fun onBind(intent: Intent): IBinder? = null
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int
- {
- thread {
- for (x in 1..100000) {
- Log.d("server", "服务器给推你推送消息啦(叮咚声响),消息内容是:${x}")
- MyLiveData.data1.postValue("服务器给推你推送消息啦,消息内容是:${x}")
- Thread.sleep(5000) // 2秒钟推一次
- }
- }
- return super.onStartCommand(intent, flags, startId)
- }
- }
MainActivity3.kt
- class MainActivity3 : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main3)
- val button = findViewById
- button.setOnClickListener {
- MyLiveData.value1.value = "我就是我,不一样的烟火"
- startActivity(Intent(this, MainActivity4::class.java))
- }
- }
- }
MainActivity4.kt
- class MainActivity4 : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main4)
- MyLiveData.value1.observe(this, {
- Toast.makeText(this, "观察者数据变化:$it", Toast.LENGTH_SHORT).show()
- })
- }
- }
MyLiveData.kt
- object MyLiveData {
- // 这里为info1的MutableLiveData 懒加载初始化(懒加载:用到时才加载)
- val value1 : MutableLiveData
by lazy { MutableLiveData() } - }

继承了LiveData是一个可变的LiveData
是一个被观察者,是一个数据持有者
提供了 setValue 和 postValue方法,其中postValue可以在子线程调用
postValue方法,我们下面会具体分析
- public class MutableLiveData
extends LiveData { -
- /**
- * Creates a MutableLiveData initialized with the given {@code value}.
- *
- * @param value initial value
- */
- public MutableLiveData(T value) {
- super(value);
- }
-
- /**
- * Creates a MutableLiveData with no value assigned to it.
- */
- public MutableLiveData() {
- super();
- }
-
- @Override
- public void postValue(T value) {
- super.postValue(value);
- }
-
- @Override
- public void setValue(T value) {
- super.setValue(value);
- }
- }
此接口是宿主生命周期的代表
- public interface LifecycleOwner{
- @NonNull Lifecycle getLifecycle();
- }
Observer是一个观察者
Observer中有一个回调方法,在 LiveData 数据改变时会回调此方法
- public interface Observer
{ - /**
- * 当数据改变时调用。
- * @param t 新数据
- */
- void onChanged(T t);
- }
首先我们上面示例中的 LiveData.observe()方法开始。
- class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- val textView: TextView = findViewById(R.id.tv_textview)
- MyLiveData.info1.observe(this, {
- textView.text = it
- })
- thread {
- Thread.sleep(3000)
- MyLiveData.info1.postValue("三秒钟后,修改了哦")
- }
- thread {
- Thread.sleep(6000)
- MyLiveData.info1.postValue("六秒钟后,修改了哦")
- }
- }
- }
我们点进observe方法中去它的源码
- @MainThread
- public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T>
- observer) {
- assertMainThread("observe");
- // 一:首先会通过LifecycleOwner获取Lifecycle对象然后获取Lifecycle 的State,如果是DESTROYED直接 return 了。忽略这次订阅
- if (owner.getLifecycle().getCurrentState() == DESTROYED) {
- // ignore
- return;
- }
- // 二:把LifecycleOwner和Observer包装成LifecycleBoundObserver对象,至于为什么包装成这个对象,我们下面具体讲,而且这个是重点。
- LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner,
- observer);
- // 三:把观察者存到 Map 中
- ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
- // 四:之前添加过LifecycleBoundObserver,并且LifecycleOwner不是同一个,就抛异常
- if (existing != null && !existing.isAttachedTo(owner)) {
- throw new IllegalArgumentException("Cannot add the same observer"
- + " with different lifecycles");
- }
- if (existing != null) {
- return;
- }
- // 五:通过Lifecycle和添加 LifecycleBoundObserver观察者,形成订阅关系
- owner.getLifecycle().addObserver(wrapper);
- }
到现在,我们知道了LiveData的observe方法中会判断 Lifecycle 的生命周期,
会把LifecycleOwner和Observer包装成LifecycleBoundObserver对象,
然后 Lifecycle().addObserver(wrapper)
Lifecycle 这个被观察者会在合适的时机 通知 观察者的回调方法。
- thread {
- Thread.sleep(3000)
- MyLiveData.info1.postValue("三秒钟后,修改了哦")
- }
- thread {
- Thread.sleep(6000)
- MyLiveData.info1.postValue("六秒钟后,修改了哦")
- }
在点击按钮的时候 LiveData会调用postValue ----> setValue方法,来更新最新的值,这时候我们
的观察者Observer就会收到回调,来更新 TextView。
所以接下来我们先看下 LiveData的setValue方法做了什么,LiveData还有一个postValue方法,我
们也一并分析一下。
- // LiveData.java
- @MainThread
- protected void setValue(T value){
- assertMainThread("setValue");
- mVersion++;
- mData=value;
- dispatchingValue(null); // 注意:这里的分发value值
- }
调用了dispatchingValue方法,继续跟代码
- void dispatchingValue(@Nullable ObserverWrapper initiator) {
- if (mDispatchingValue) {
- mDispatchInvalidated = true;
- return;
- }
- mDispatchingValue = true;
- do {
- mDispatchInvalidated = false;
- if (initiator != null) { // 如果传递进来的 非null,就进此if
- considerNotify(initiator);
- 不管如何判断,都是调用了considerNotify() 方法
- initiator = null;
- } else { // 如果传递进来的 null,就进此if
- for (Iterator
super T>, ObserverWrapper>> - iterator =
- mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
- considerNotify(iterator.next().getValue());
- 不管如何判断,都是调用了
- considerNotify() 方法
- 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.mObserver就是我们的 Observer接口,然后调用它的onChanged方法。
- observer.mObserver.onChanged((T) mData);
- // 恭喜恭喜 :到现在整个被观察者数据更新通知观察者这个流程就通了。
- }
子线程发送消息通知更新 UI,嗯?Handler 的味道
- // LiveData.java
- protected void postValue(T value) {
- boolean postTask;
- synchronized (mDataLock) {
- postTask = mPendingData == NOT_SET;
- mPendingData = value;
- }
- if (!postTask) {
- return;
- }
- // 利用Handler切换到主线程去执行
- ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
- }
可以看到一行关键代码
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
点 postToMainThread 方法进去看下
- // ArchTaskExecutor.java
- privateTaskExecutor mDelegate;
-
- @Override
- public void postToMainThread(Runnable runnable) {
- mDelegate.postToMainThread(runnable);
- }
看到 mDelegate 是 TaskExecutor对象,现在目标是看下 mDelegate 的具体实例对象是谁
- // ArchTaskExecutor.java
- private ArchTaskExecutor(){
- mDefaultTaskExecutor=new DefaultTaskExecutor();
- mDelegate=mDefaultTaskExecutor; // 目前的重点是看下DefaultTaskExecutor是个啥
- }
然后看它的postToMainThread方法
- // DefaultTaskExecutor.java
- privatevolatileHandler mMainHandler;
-
- @Override
- public void postToMainThread(Runnable runnable) {
- if (mMainHandler == null) {
- synchronized (mLock) {
- if (mMainHandler == null) {
- // 实例了一个 Handler 对象,注意构造参数 Looper.getMainLooper() 是主线的 Looper。
- // 那么就可做到线程切换了。
- mMainHandler = new Handler(Looper.getMainLooper()); // 注意:这里主
- 线程已经切换过来了
- }
- }
- }
- //noinspection ConstantConditions
- // 调用post 方法 注意:重点看runnable,这里面就是真正主线程的执行功能了
- mMainHandler.post(runnable);
- }
下面看下这个 Runnable
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
这里面的方法参数是mPostValueRunnable是个 Runnable,我们看下代码
- // LiveData.java
- private final Runnable mPostValueRunnable = new Runnable() {
- @Override
- public void run() {
- Object newValue;
- synchronized (mDataLock) {
- newValue = mPendingData;
- mPendingData = NOT_SET;
- }
- //noinspection unchecked
- // 注意:postValue方法其实最终调用也是setValue方法,然后和setValue方法走的流程就是一样的了,
- // 这个上面已经分析过了
- setValue((T) newValue);
- }
- };
我们要详细看一下LifecycleBoundObserver类了,它包装了LifecycleOwner和Observer,这就是
接下来的重点内容了。
- @MainThread
- public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T>
- observer) {
- assertMainThread("observe");
- if (owner.getLifecycle().getCurrentState() == DESTROYED) {
- // ignore
- return;
- }
- // 用LifecycleBoundObserver对LifecycleOwner 和 Observer进行了包装
- 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);
- }
来看下LifecycleBoundObserver类,它是LiveData的内部类
- class LifecycleBoundObserver extends ObserverWrapper implements
- GenericLifecycleObserver {
- @NonNull
- final LifecycleOwner mOwner;
- LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer super T>
- observer) {
- super(observer);
- mOwner = owner;
- }
- }
两个参数,一个 owner被成员变量mOwner存储,observer参数被ObserverWrapper的 mObserver存储。
LifecycleEventObserver是LifecycleObserver的子接口里面有一个onStateChanged方法,这个方法会在 Activity、Fragment 生命周期回调时调用(这个和Lifecycle有关)
ObserverWrapper 是Observer包装类
活跃状态指的是 Activity、Fragment 等生命周期处于活跃状态
- private abstract class ObserverWrapper {
- final Observer super T> mObserver;
- boolean mActive;
- int mLastVersion = START_VERSION;
-
- // 获取了我们的 Observer 对象,存储在 成员变量mObserver身上
- 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) {
- // 可以继承 LiveData 来达到扩展 LiveData 的目标,并且是在活跃的状态调用
- onActive();
- }
- if (LiveData.this.mActiveCount == 0 && !mActive) {
- // 可以继承 LiveData 来达到扩展 LiveData 的目标,并且是在非活跃的状态调用
- onInactive();
- }
- if (mActive) {
- // 活跃状态,发送最新的值,来达到通知的作用,dispatchingValue(this) 方法咋这么眼熟,
- // 对之前在 LiveData 调用 setValue 方法时,最终也会调用到此方法。
- // 那ObserverWrapper类中的dispatchingValue这个方法是在activeStateChanged方法中调用,
- // 那activeStateChanged啥时候调用呢?
- // 我来看下ObserverWrapper的子类也就是最重要的那个类LifecycleBoundObserver,
- // 现在看它的完整代码(看下面代码 LifecycleBoundObserver完整代码)
- dispatchingValue(this);
- }
- }
- }
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() {
- // 判断当前的 Lifecycle 的生命周期是否是活跃状态,会在回调观察则 Observer 的时候进行判断,
- // 只有在活跃状态,才会回调观察者Observer的onChanged方法。
- return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
- }
-
- @Override
- public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
- // onStateChanged每次 Activity、Fragment的生命周期回调的时候,都会走这个方法。
- // 获取Lifecycle对象然后获取Lifecycle 的State如果为DESTROYED则移除观察者,
- // 在 Activity、Fragment的生命周期走到 onDestroy 的时候,就会取消订阅,避免内存泄漏。
- if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
- removeObserver(mObserver);
- return;
- }
- // 调用父类ObserverWrapper 的activeStateChanged方法,
- // 层层调用到观察者Observer的onChanged方法。(自己看下源码一目了然)
- activeStateChanged(shouldBeActive());
- }
-
- @Override
- boolean isAttachedTo(LifecycleOwner owner) {
- return mOwner == owner;
- }
-
- @Override
- void detachObserver() {
- // 移除观察者Observer,解除订阅关系。
- mOwner.getLifecycle().removeObserver(this);
- }
- }
JLiveDataBus.kt
- object JLiveDataBus {
-
- private const val TAG = "JLiveDataBus"
-
- private val busMap: MutableMap
> by lazy { HashMap>() } -
- @Synchronized
- fun
with(key: String, type: Class<T>, isStick: Boolean = true): BusMutableLiveData { - Log.d(TAG, "with isStick $isStick")
- if (!busMap.containsKey(key)) {
- busMap[key] = BusMutableLiveData(isStick)
- } else {
- (busMap[key] as BusMutableLiveData
).isStick = isStick - }
- return busMap[key] as BusMutableLiveData
- }
-
-
- class BusMutableLiveData<T> private constructor() : MutableLiveData
() { -
- // 启用粘性事件
- var isStick: Boolean = false
-
- // 次构造函数,必须调用主构造函数
- constructor(isStick: Boolean) : this() {
- Log.d(TAG, "constructor isStick $isStick")
- this.isStick = isStick
- }
-
- // 重写 增加hook
- override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
- super.observe(owner, observer)
- if (!isStick) {
- // 不启用粘性事件
- hook(observer = observer)
- Log.d(TAG, "不启动粘性事件")
- } else {
- Log.d(TAG, "启动粘性事件")
- }
- }
-
- private fun hook(observer: Observer<in T>) {
- // TODO 1.利用反射得到mLastVersion
- // 获取到LiveData类中的mObservers对象
- val liveDataClass = LiveData::class.java
- val mObserversField: Field = liveDataClass.getDeclaredField("mObservers")
- // 设置权限,私有修饰也可以访问
- mObserversField.isAccessible = true
- // 获取到mObservers这个成员变量的对象
- val mObservers: Any = mObserversField.get(this)
- // 获取到mObservers的class对象
- val mObserversClass: Class<*> = mObservers.javaClass
- // 获取到mObservers对象的get方法
- val get: Method = mObserversClass.getDeclaredMethod("get", Any::class.java)
- get.isAccessible = true
- // 执行get方法
- val invokeEntry: Any = get.invoke(mObservers, observer)
- // 获取到entry中的value
- var observerWraper: Any? = null
- if (invokeEntry != null && invokeEntry is Map.Entry<*, *>) {
- observerWraper = invokeEntry.value
- }
- if (observerWraper == null) {
- throw NullPointerException("observerWraper is null.")
- }
- // 获取到observerWraper的类对象
- val supperClass: Class<*> = observerWraper.javaClass.superclass!!
- val mLastVersion: Field = supperClass.getDeclaredField("mLastVersion")
- mLastVersion.isAccessible = true
-
- // TODO 2.得到mVersion
- val mVersion: Field = liveDataClass.getDeclaredField("mVersion")
- mVersion.isAccessible = true
-
- // TODO 3.mLastVersion = mVersion
- val mVersionValue: Any = mVersion.get(this)
- mLastVersion.set(observerWraper, mVersionValue)
- }
- }
-
- }
BusActivity.kt
- class BusActivity : AppCompatActivity() {
-
- private lateinit var binding: ActivityBusBinding
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- binding = ActivityBusBinding.inflate(layoutInflater)
- setContentView(binding.root)
-
- JLiveDataBus.with("test1", String::class.java, false).observe(this) {
- binding.busTv.text = it
- }
-
- thread {
- Thread.sleep(2000)
- JLiveDataBus.with("test1", String::class.java).postValue("新数据")
- }
-
- }
- }
startActivity
- JLiveDataBus.with("test1", String::class.java).value = "老数据"
- textView.setOnClickListener {
- startActivity(Intent(activity, BusActivity::class.java))
- }
由于我们在BusActivity使用的是不启用粘性,JLiveDataBus.with("test1", String::class.java, false).observe(this),所以当BusActivity启动时不会调用binding.busTv.text = "老数据",延迟2S后,正常接收到启动后的 新数据。