美文网首页
Android Jetpack 之 LiveData

Android Jetpack 之 LiveData

作者: gerryjia | 来源:发表于2019-11-19 18:40 被阅读0次

LiveData是什么

学习LiveData首先要明白,LiveData 是什么

LiveData具有生命周期感知功能的可观察的数据持有者类。 LiveData只会将有关更新的信息通知给处于STARTED或RESUMED状态的观察者。

为什么要用LiveData

官方给我们提供了LiveData的以下几个特性:

1. 确保UI与数据状态的统一 :
LiveData遵循观察者模式。当数据发生变化时,LiveData会通知Observer对象。
2. 没有内存泄漏:
Observer绑定到生命周期对象,并在其关联的生命周期对象处于DESTORY状态时,Observer对象会被清理掉。
3. 当Activitys停止时不会引起崩溃:
因为组件处于非激活状态时,不会收到LiveData中数据变化的通知。
4. 不再需要额外的手动处理生命周期导致的变化:
因为LiveData能够感知组件的生命周期,所以就完全不需要在代码中告诉LiveData组件的生命周期状态。
5. 一直都是最新的数据:
当lifecycle一直是活跃状态时,数据肯定是最新的。如果lifecycle是处于非活跃状态,当它重新变为活跃状态时,也会接收到最新的数据。例如:在后台的Activity返回到前台后立即接收最新的数据。
6. 遵守configuration change的规则:
如果由于配置更改(例如设备旋转)而重新创建Activity或Fragment,则该Activity或Fragment将立即接收最新的可用数据。
7. 资源共享:
通过继承LiveData类,然后将该类定义成单例模式,可以在应用程序中共享它们。 LiveData对象一旦连接到系统服务,然后任何需要资源的观察者都可以观看LiveData对象。

怎么用LiveData

直接使用LiveData

  1. 创建LiveData实例以保存某种类型的数据。这通常是在ViewModel类中完成的。
  2. 创建一个带有onChanged()方法的Observer对象,作为参数传入LiveData.observe()方法添加观察者。通常,可以在UI controller中创建一个Observer对象,例如Activity或Fragment。
  3. 更新Livedata对象中存储的数据;

按照上边的步骤,官方给了我们一个简单的案例:

class NameViewModel : ViewModel() {
    // 创建一个LiveData实例保存String类型的数据
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    val currentNum: MutableLiveData<Int> by lazy {
        MutableLiveData<Int>()
    }

}

class MainActivity : AppCompatActivity() {
    val TAG = "MainActivity"
    private lateinit var model: NameViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //获取NameViewModel
        model = ViewModelProvider(this).get(NameViewModel::class.java)
        //创建一个Observer用来刷新UI
        val nameObserver = Observer<String> { t -> text_main.text = t }
        //观察LiveData,并以LifecycleOwner和观察者的身份传入此Activity。
        model.currentName.observe(this, nameObserver)

        button.setOnClickListener {
            val anotherName = "gerry"
            model.currentName.value = anotherName
        }
    }
}

model.currentName.value = anotherName对value的设置有两个方法,一个是setValue(),一个是postValue()。setValue()的方式只能在主线程也就是UI线程里面调用,postValue()的方式可以在主线程或者子线程里面调用。

Transform LiveData

Transform有2个方法,一个是map(),一个是switchMap()。

class MainActivity : AppCompatActivity() {
    val TAG = "MainActivity"
    private lateinit var model: NameViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        model = ViewModelProvider(this).get(NameViewModel::class.java)

        val nameObserver = Observer<String> { t -> text_name.text = t }

        val numObserver = Observer<Int> { t: Int? -> text_num.text = t.toString() }

        // 在LiveData对象分发给观察者之前对其中存储的值进行更改
        Transformations.map(model.currentName) { "Hello,LiveData!" }.observe(this, nameObserver)

        // 在LiveData对象分发给观察者之前可以将LiveData对象改为另一个LiveData对象
        Transformations.switchMap(model.currentName) { model.currentNum }.observe(this, numObserver)

        button_1.setOnClickListener {
            val anotherName = "gerry"
            model.currentName.value = anotherName
        }

        button_2.setOnClickListener {
            val anotherName = "gerry"
            model.currentName.value =anotherName

            model.currentNum.value = 12
        }
    }
}

合并LiveData

MediatorLiveData是LiveData的子类,允许合并多个LiveData源。每当任何原始LiveData源对象发生更改时,就会触发MediatorLiveData对象的观察者。

class MainActivity : AppCompatActivity() {
    val TAG = "MainActivity"
    private lateinit var model: NameViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        model = ViewModelProvider(this).get(NameViewModel::class.java)


        val nameObserver = Observer<String> { t -> text_name.text = t }

        val mediatorLiveData = MediatorLiveData<String>()
        mediatorLiveData.addSource(model.currentNum) { t -> mediatorLiveData.value = t.toString() }
        mediatorLiveData.addSource(model.currentName) { t -> mediatorLiveData.value = t }
        mediatorLiveData.observe(this, nameObserver)

        button_1.setOnClickListener {
            val anotherName = "gerry"
            model.currentName.value = anotherName
        }

        button_2.setOnClickListener {
            val anotherName = "gerry"
            model.currentName.value = anotherName

            model.currentNum.value = 12
        }
    }
}

LiveData的实现原理

1. LiveData是怎么和LifecycleOwner 进行绑定,做到感知生命周期的

LiveData是从observer开始的,我们看一下observer()的代码。

    private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();
    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        //如果是 DESTROYED 的状态则忽略
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        //将LifecycleOwner对象和Observer对象封装成LifecycleBoundObserver对象。
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        //mObservers是一个类似map的容器。
        //putIfAbsent()方法是判断容器中的key值observer是否有已经和键值wrapper关联,如果已经关联则返回关联值,否则进行关联并返回null。
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
         //如果返回值不是null  并且两次的 owner 不同则报错
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        //添加LifecycleOwner的生命周期观察者
        owner.getLifecycle().addObserver(wrapper);
    }

在LiveData.observe()方法中给LifecycleOwner添加了生命周期观察者。而这个观察者就是LifecycleBoundObserver对象,下面我们看下LifecycleBoundObserver具体实现。

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

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }

        @Override
        boolean shouldBeActive() {
            //重写了shouldBeActive方法,用于判断当前传入的组件的状态是否是Active的,Active状态包括STARTED和RESUMED状态。
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        // LifecycleOwner对象生命周期发生变化时,会通过该回调方法通知过来。
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            // 如果当前处于Lifecycle.State.DESTROYED时,会自动将观察者移除。
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            // 判断是否处于actived状态,并将结果作为参数传递给activeStateChanged()
            activeStateChanged(shouldBeActive());
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

    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) {//处于激活状态的observer个数从0到1
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {//处于激活状态的observer个数从1变为0
                onInactive();
            }
            //如果 active 状态下,则发送数据更新通知
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }

接下来看dispatchValue()方法

    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        //如果正在分发则直接返回
        if (mDispatchingValue) {
            //分发无效
            mDispatchInvalidated = true;
            return;
        }
        //标记分发开始
        mDispatchingValue = true;
        do {
            //分发有效
            mDispatchInvalidated = false;
            if (initiator != null) {//如果 initiator不为空,调用considerNotify方法
                considerNotify(initiator);
                initiator = null;
            } else {//postValue/setValue 方法调用 传递的 initiator 为 null
                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方法():

    private void considerNotify(ObserverWrapper observer) {
        //检查状态 确保不会分发给 inactive 的 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;
        }
        //setValue 会增加 version ,初始 version 为-1
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        // 最终回调的地方,也就是调用observe()或者observeForever()是传入的Observer对象。
        observer.mObserver.onChanged((T) mData);
    }

dispatchValue(@Nullable ObserverWrapper initiator)方法的参数有两种情况,一种是initiator是null,一种是initiator不为null。

initiator不为null:

LifecycleBoundObserver.onStateChanged 方法里调用了 activeStateChanged ,而该方法调用dispatchingValue(this);传入了 this ,也就是 LifecycleBoundObserver ,这时候不为 null 。
也就是说生命周期改变触发的流程就是这种情况,这种情况下,只会通知跟该 Owner 绑定的 Observer。

initiator为null:

当是postValue或者是setValue时,initiator为null。

2. postValue()和setValue()方法
private final Runnable mPostValueRunnable = new Runnable() {
    @Override
    public void run() {
        Object newValue;
        synchronized (mDataLock) {
            newValue = mPendingData;
            mPendingData = NOT_SET;
        }
        //noinspection unchecked
        //调用 setValue
        setValue((T) newValue);
    }
};

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    if (!postTask) {
        return;
    }
    // 会在主线程中执行  mPostValueRunnable中的内容。
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

@MainThread
protected void setValue(T value) {
    //判断当前线程是否是主线程,不是主线程就抛出异常
    assertMainThread("setValue");
    mVersion++;//增加版本号
    mData = value;
    //传入了 null
    dispatchingValue(null);
}
3. 参考与推荐

http://liuwangshu.cn/application/jetpack/5-livedata-theory.html
https://juejin.im/post/5ce54c2be51d45106343179d#heading-18
https://blog.csdn.net/zhuzp_blog/article/details/78871527
https://developer.android.google.cn/topic/libraries/architecture/livedata#kotlin

相关文章

网友评论

      本文标题:Android Jetpack 之 LiveData

      本文链接:https://www.haomeiwen.com/subject/drlrictx.html