LiveData的介绍和源码分析

428 阅读7分钟

一 概述

LiveData 是一种可观察的存储数据类型。与常规的可观察类不同,LiveData 可以感应 Activity、Fragment 或 Service 的生命周期。只会通知处于活跃生命周期状态的观察者。比如当观察者生命周期处于 STARTED 或 RESUMED状态的时候,此时的状态包括 生命周期处于 onStart(),onResume(),onPause() 三种,LiveData才会去通知。同时,当观察者处于 DESTROYED 时,LiveData会移除观察者。不用担心泄漏。当 Activty 或者 Fragment 处于 onStart(),onResume(),onPause() 的生命周期下,会接收到 ,onStop 是收到的

二 LiveData优点

  1. 确保UI与数据匹配 LiveData本身用的就是观察者模式,当数据源改变的时候会通知观察者,及时更新UI

  2. 没有内存泄漏 观察者是绑定到 Lifecycle 对象上的,当Lifecycle处于destory的时候会自动清理这个观察者

  3. 不会因为 Activity处于onStop的状态 而 crash 如果观察者的生命周期处于 inactive (不活跃)状态是不会收到事件的,比如回退栈的Activity

  4. 不需要手动处理生命周期 LiveData可以感知被绑定的组件的生命周期,只有在活跃状态才会通知数据变化。

  5. 始终保持最新数据 如果 生命周期 处于非活跃状态,当他再次进入活跃状态的时候,他会拿到最新的数据,并且更新。比如回退栈中的 Activity 在onStop的时候,处于不活跃状态,此时不会通知Activity的,当Activity 再次处于onStart 或者 onResume的时候,再次拿到最新的数据

  6. 解决了通过 configuration 改变的问题 如果由于 configuration 改变(旋转屏幕)而重新创建的Activity或者Fragment,它会立即拿到最新的数据

  7. 共享资源(我感觉主要是在本app中实现EventBus的作用) 您可以使用单一实例模式扩展 LiveData 对象以封装系统服务,以便在app中共享它们

缺点是有的

  1. 默认是粘性事件,如果你提前更改了一个LiveData值,如果此时再打开一个Activity 的话 就会根据version立即执行 监听事件,有的时候不是我们要的,可以在写一个类继承MutilLivewData,当 observe 的时候,我们我们可以通过反射 把mLastVersion 修改成 当前LiveData的 mVersion ,让他们相等
  2. 在Activity 和 Fragment 的生命周期 的onStop的时候 并不会 回调监听,需要再执行 onResume的时候,才去更改
  3. postValue 会丢失数据,原因是,如果连续两次postValue 他用的一个runable ,只是更改了里面的值,
  4. 当onStop 的时候,如果 setValue 好几次,在onResume的时候 只会执行最后的一个

大概原理

  1. 当我们调用 liveData.observe(this, Observer),他会注册这个Actvitiy生命周期回调 owner.getLifecycle().addObserver(wrapper);
  2. 当Activity的生命周期触发的时候,他会判断是否 这个LiveData的version 大于 这个 Observer mLastVersion ,如果大于,直接触发,同时只有再活跃的时候 比如 Activity 的 onresume onpause,才开是触发
  3. 每当 setValue 的时候 都会 把LiveData的 version +1,当Activity 不活跃的时候 ,不会触发,只有再活跃的是后续,才会触发,他的驱动 可以是认为 Activity 生命周期的驱动

三 使用

创建 LiveData 实例以存储某种类型的数据。这通常在 ViewModel 类中完成。在Activity 或者 Fragment中添加观察者,通常我们使用的是LiveData的一个子类 MutableLiveData,LiveData主要是用来存储不可变的对象,MutableLiveData是可以存储随时变化的类,在ViewModel中主要使用 MutableLiveData,观察者模式我上个文章已经写过简单例子了可以去看一下()

简单写一个计数器

先写一个ViewModel

class TimeViewModel : ViewModel() {
    var time = 0
    val timeMutableLiveData: MutableLiveData<Int> by lazy {
        time = 0
        getTime()
        MutableLiveData<Int>()
    }


    private fun getTime() {
    // 启动协程 延时1s 更改数据
        viewModelScope.launch {
            delay(1000)
            timeMutableLiveData.value = ++time
            getTime()
        }
    }
}

Activity中使用,observe 方法来观察数据 , observe 方法会察觉Activity的生命周期,observeForever 在 Activity不活跃的状态也会去通知观察者。但是系统不会主动remove此观察者,需要我们手动去removeObserver

class LiveDataActivity : AppCompatActivity() {

    // 赖加载 ViewModel
    private val viewModel: TimeViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        var binding = DataBindingUtil.setContentView<ActivityLivedataBinding>(
            this,
            R.layout.activity_livedata
        )
        // 开始观察数据
        viewModel.timeMutableLiveData.observe(this, Observer {
            tv_time.text = "${it}秒"
        })
    }

四 源码解析

4.1 observe 方法

@MainThread
 public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
 // 先判断是不是主线程,如果不是主线程直接抛 异常
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
           // 如果 LifecycleOwner 的是生命周期已经处于 onDestroye的时候,直接return
            return;
        }
        
        // LifecycleBoundObserver 是一个包装类,包装着LifecycleOwner和Observer 
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        // mObservers 是存储 observer 和 wrapper的一个类,类似于HashMap,observer当做key ,wrapper当做value
        // 存起来,如果以前存过这个wrapper,就返回以前的wrapper
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        // 被观察者不能观察一个Actitiy或者Fragment多次,否则直接抛异常
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        // 如果存在过,就不会再添加到观察者中
        if (existing != null) {
            return;
        }
        // 添加 Activity 或者 Fragment的生命周期观察者,当生命周期改变的时候 会调用 LifecycleBoundObserver 的 onStateChanged方法
        owner.getLifecycle().addObserver(wrapper);
    }

然后我们再看一下 LifecycleBoundObserver 类 和 他的父类 ObserverWrapper , 这两个都是LiveData的内部类

class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }
        // 当 LifecycleOwner 处于 STARTED 和 RESUME的时候,返回true
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        // 当 LifecycleOwner (Activity 或者 Fragment)的生命周期发生变化的时候调用
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
                // 再次判断 LifecycleOwner 是否已经desroy 。如果销毁 直接移除观察者
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            // 调用父类的方法
            activeStateChanged(shouldBeActive());
        }

        // 判断是否已经添加过 LifecycleOwner
        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }
        
        //移除此LifecycleOwner生命周期的观察者
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

然后再看看他的父类 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;
            }
            mActive = newActive;
            // 用 mActiveCount 计数相加法来判断 活跃的个数
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            LiveData.this.mActiveCount += mActive ? 1 : -1;
            if (wasInactive && mActive) {
            // 当有活跃的时候 走这里 onActive 是 LiveData的方法,
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
                onInactive();
            }
            // 这个是当Activity从stop再次回到start时候会走到这里
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }

然后我们再看一下 LiveData 的 dispatchingValue 方法,用来 分发value

void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
            // 如果传过来的不是null,直接通知观察者,改变数据
                considerNotify(initiator);
                initiator = null;
            } else {
            // 当传过来是null的时候,直接去更新下面的数据 considerNotify
                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

 @SuppressWarnings("unchecked")
    private void considerNotify(ObserverWrapper observer) {
        // 如果observer处于非活跃状态  直接return
        if (!observer.mActive) {
            return;
        }
        
        // 如果 不处于 ONSTART 或者 ONRESUME 继续走 ObserverWrapper的 activeStateChanged方法。
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        // 用来记录通知的版本,如果通知过了,就不用再通知了,很明显的一个例子,在onStart()已经通知了,在onResume就不会再通知了,
        //每一个新注册的观察者,其version都为-1,所以当已经更改过的LiveData,当有一个新的观察者的时候,会直接拿到最新的 数据
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        // 记录此次的 version
        observer.mLastVersion = mVersion;
        // 通知观察者
        observer.mObserver.onChanged((T) mData);
    }

4.2 setValue(T value) 方法


@MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        //  上面有这个方法的作用
        dispatchingValue(null);
    }


4.3 postValue(T value) 方法,在子线程中该数据

       protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        // 启动一个线程池,直接post到主线程
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

用LiveData 做两个例子 一个是 实现EventBus功能,另一个是6.0运行时权限demo