framework通信机制—LiveData使用方法及原理

LiveData是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 activity、fragment 或 service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

使用 LiveData 的优势

使用 LiveData 具有以下优势:

  • 确保界面符合数据状态LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知Observer对象。您可以整合代码以在这些Observer对象中更新界面。这样一来,您无需在每次应用数据发生变化时更新界面,因为观察者会替您完成更新。
  • 不会发生内存泄漏观察者会绑定到Lifecycle对象,并在其关联的生命周期遭到销毁后进行自我清理。
  • 不会因 Activity 停止而导致崩溃如果观察者的生命周期处于非活跃状态(如返回堆栈中的 activity),它便不会接收任何 LiveData 事件。
  • 不再需要手动处理生命周期界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
  • 数据始终保持最新状态如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
  • 适当的配置更改如果由于配置更改(如设备旋转)而重新创建了 activity 或 fragment,它会立即接收最新的可用数据。
  • 共享资源您可以使用单例模式扩展LiveData对象以封装系统服务,以便在应用中共享它们。LiveData对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察LiveData对象。如需了解详情,请参阅扩展 LiveData。

LiveData的几种用法

声明一个LiveData

我们发现LiveData是一个抽象类,它的默认实现子类是MutableLiveData,但是看源码他们没有区别~唯一区别就是set和post方法公开了,之所以这么设计,是考虑到单一开闭原则,只有拿到 MutableLiveData 对象才可以发送消息,LiveData 对象只能接收消息,避免拿到 LiveData 对象时既能发消息也能收消息的混乱使用。

//1.声明一个MutableLiveData
val data = MutableLiveData("Test")


fun main(){
    //2.监听数据源变化
    data.observe(this){ data->
        //...do somethig
    }
}

组合多个LiveData统一观察

当我们有多个LiveData时候,某些场景下我们想统一监听,那这个时候我们可以使用MediatorLiveData来对多个LiveData进行统一监听。

//创建两个长得差不多的LiveData对象
LiveData liveData1 =  new MutableLiveData();
LiveData liveData2 = new MutableLiveData();


 //再创建一个聚合类MediatorLiveData
 MediatorLiveData liveDataMerger = new MediatorLiveData<>();
 //分别把上面创建LiveData 添加进来。
liveDataMerger.addSource(liveData1, observer);
liveDataMerger.addSource(liveData2, observer);


Observer observer = new Observer() {
  @Override
 public void onChanged(@Nullable Integer s) {
      titleTextView.setText(s);
 }
//一旦liveData或liveData发送了新的数据 ,observer便能观察的到,以便  统一处理更新UI

转换数据

比如我们希望对一个Int值的LiveData在监听里变成String,那么我们可以用到Transformations.map 操作符进行该操作

MutableLiveData data = new MutableLiveData<>();


//数据转换
LiveData transformData = Transformations.map(data, input ->   String.valueOf(input));
//使用转换后生成的transformData去观察数据
transformData.observe( this, output -> {


});


//使用原始的livedata发送数据
data.setValue(10);

LiveData实现原理

观察者生命周期

observe方法负责建立生命周期绑定关系,并注册观察者,如下所示:



    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer 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);
    }

LiveData将Observer对象加入mObservers中,数据变更时会遍历这个Map分发最新数据。LifecycleBoundObserver类负责监听应用组件的生命周期变化,如下所示:

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


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


        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }


        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }


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


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

如onStateChanged方法所示,Lifecycle.State为DESTROYED时,移除观察者,其他情况则更改观察者的状态。

数据分发

有两个方法触发数据分发,一个是setValue,在数据变更时触发;一个是ObserverWrapper的activeStateChanged方法,在生命周期变更是触发(例如,从后台切换到前台),就是这个方法确保了应用组件的数据始终是最新的。如下所示:



    private abstract class ObserverWrapper {
        final Observer mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;


        ObserverWrapper(Observer observer) {
            mObserver = observer;
        }


        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, so we'd never dispatch anything to inactive
            // owner
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }


   @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }


    @SuppressWarnings("WeakerAccess") /* synthetic access */
    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;
    }


    @SuppressWarnings("unchecked")
    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;
        observer.mObserver.onChanged((T) mData);
    }

considerNotify方法负责实际的数据分发,如果观察者处于非激活态则不分发数据,否则有最新的数据就会分发到观察者,即调用onChanged((T) mData)方法。

本文主要讲解framework通信机制中的LiveData的用法以及原理,更多有关framework通信技术可以参考《framework全家桶手册》点击可查看详细内容。

framework通信机制—LiveData使用方法及原理_第1张图片

你可能感兴趣的:(framework,开发语言,Android开发,程序员,面试,Android,framework,livedata)