Android开发Android开发Android技术知识

Android源码解析:LiveData

2018-12-17  本文已影响2人  小村医

概述

简单地来说,LiveData就是一个持有数据的类。

LiveData中的数据可以被观察者订阅,当数据被修改时通知观察者。观察者包括Fragment、Activity以及Service等。
LiveData能够感知观察者的生命周期。只有在观察者处于激活状态(STARTED之后的状态)才会收到数据更新;并在onDestroy时自动解注册观察者,避免崩溃,且减少内存泄露。

使用

使用LiveData子类MutableLiveData,维护一个String类型的数据:

public class MyViewModel extends ViewModel{
    private MutableLiveData<String> mData;
    public MutableLiveData<String> getData() {
        if (mData == null) {
            mData = new MutableLiveData<>();
        }
        return mData;
    }
    public void setData(String data){
        //更新livedata中的值
        mData.setValue(data);
    }
}

接着注册观察者:


public class LiveDataFragment extends Activity{
    private MyViewModel mViewModel;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
        mViewModel.getData().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String data) {
                //LiveData数据变化后的回调
            }
        });
    }
}

主要类

LiveData类图.png

源码分析

从以下几个方面对源码进行分析:

1. 如何注册观察者

     public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // 当前Activity/Fragment为destory状态时忽略
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        //mObservers(一个类似Map的容器)的putIfAbsent()方法用于判断容器中的observer是否有已经和wrapper关联,
        //如果已关联则返回关联值,否则关联之后并返回wrapper
        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;
        }
       //使用上面new的wrapper对象监听Activity/Fragment的生命周期
        owner.getLifecycle().addObserver(wrapper);
    }

LifecycleBoundObserver继承自ObserverWrapper对象并实现GenericLifecycleObserver接口,当组件的生命周期发生变化后会通过onStateChanged()方法回调过来通知ObserverWrapper生命周期变化

2. 如何监听Activity/Fragment的生命周期

通过上面的分析,可以知道组件生命周期的观察者就是LifecycleBoundObserver对象,下面我们看一下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() {
            // 判断组件是否active
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                //组件destory后移除监听者
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

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

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

当组件生命周期发生变化时,onStateChanged()方法会被调用。如果当前处于Lifecycle.State.DESTROYED时,会自动将观察者移除;若当前处于ACTIVE状态,则继续执行,调用activeStateChanged方法,该方法在ObserverWrapper中实现

        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            //设置当前监听的组件是否active,只有处于active状态的组件才会通过观察者模式通知组件数据变化
            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);
            }
        }

最后调用的是dispatchingValue()进行数据变化时的消息通知

    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            //组件生命周期变化时initiator不为空,considerNotify直接调用Observer的onChanged方法
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                //遍历所有观察者调用onChanged通知数据变化
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

3. setValue()或postValue()方法后,通知观察者更新数据

LiveData提供了两种改变数据的方法:在主线程调用的setValue()方法,以及在子线程中调用的postValue()方法。现在看下两个方法的具体实现:

    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);
    }
    private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //最终通过Handler在主线程调用setValue
            setValue((T) newValue);
        }
    };
public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }
上一篇下一篇

猜你喜欢

热点阅读