美文网首页
LiveData源码分析

LiveData源码分析

作者: 风月寒 | 来源:发表于2021-02-04 15:14 被阅读0次

LiveData使得 数据的更新 能以观察者模式 被observer感知,且此感知只发生在 LifecycleOwner的活跃生命周期状态。

具有以下优点:

1、确保界面符合数据状态,当生命周期状态变化时,LiveData通知Observer,可以在observer中更新界面。观察者可以在生命周期状态更改时刷新界面,而不是在每次数据变化时刷新界面。

2、不会发生内存泄漏,observer会在LifecycleOwner状态变为DESTROYED后自动remove。

3、不会因 Activity 停止而导致崩溃,如果LifecycleOwner生命周期处于非活跃状态,则它不会接收任何 LiveData事件。

4、不需要手动解除观察,开发者不需要在onPause或onDestroy方法中解除对LiveData的观察,因为LiveData能感知生命周期状态变化,所以会自动管理所有这些操作。

5、数据始终保持最新状态,数据更新时 若LifecycleOwner为非活跃状态,那么会在变为活跃时接收最新数据。例如,曾经在后台的 Activity
会在返回前台后,observer立即接收最新的数据。

LiveData的使用
private MutableLiveData<String> infos;

public MutableLiveData<String> getInfo(){
        if (infos == null){
            infos = new MutableLiveData<>();
        }
        return infos;
    }
    
button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int x = myViewModel.increaseNumber();
                myViewModel.getInfo().setValue("info = " + x);
            }
        });
        
myViewModel.getInfo().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textView.setText(s);
            }
        });

这里是把livedata放在viewmodel里面。先在viewmodel定义一个livedata。然后在activity里面通过setValue(),设置数据,然后有数据改变,就会调用onChange()回调。还有一种设置数据的方法,postValue,它与setValue的区别是它在子线程操作,最后调用的还是setValue().源码在后面分析。

如果我们需要改变某个livedata的值,我们可以用map这个函数进行操作。

private MutableLiveData<Integer> liveData = new MutableLiveData<>();
public MutableLiveData<String> getLiveData(){
        LiveData<String> stringLiveData = Transformations.map(liveData, input -> {
            String s = input + " + Transformations.map";
            Log.i("zzf", "apply: " + s);
            return s;
        });
        return (MutableLiveData<String>) stringLiveData;
    }

如果想要根据某个值 切换观察不同LiveData数据,则可以使用Transformations.switchMap()方法。

MutableLiveData<String> liveData3 = new MutableLiveData<>();
MutableLiveData<String> liveData4 = new MutableLiveData<>();
MutableLiveData<Boolean> liveDataSwitch = new MutableLiveData<>();

public LiveData<String> liveDataSwitch1 = Transformations.switchMap(liveDataSwitch, input -> {
        if (input){
            return liveData3;
        }
        return liveData4;
    });

除了上面可以变换之外,还可以用MediatorLiveData来观察多个对象。
MediatorLiveData 是 LiveData 的子类,允许合并多个 LiveData 源。只要任何原始的 LiveData 源对象发生更改,就会触发 MediatorLiveData 对象的观察者。

//观察多个数据
MediatorLiveData<String> mediatorLiveData = new MediatorLiveData<>();
MutableLiveData<String> liveData5 = new MutableLiveData<>();
MutableLiveData<String> liveData6 = new MutableLiveData<>();
mediatorLiveData.addSource(liveData5, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.i("zzf", "onChanged3: " + s);
                mediatorLiveData.setValue(s);
            }
        });

        mediatorLiveData.addSource(liveData6, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.i("zzf", "onChanged4: " + s);
                mediatorLiveData.setValue(s);
            }
        });

        mediatorLiveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.i("zzf", "onChanged5: "+s);
                //无论liveData5、liveData6更新,都可以接收到
            }
        });
    }
源码分析

首先我们需要调用setValue或者postValue数据更新:

setValue
protected void setValue(T value) {
        assertMainThread("setValue");
        //版本号
        mVersion++;
        mData = value;
        //分发数据
        dispatchingValue(null);
    }
postValue
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() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };

从上面可以看出postValue调用线程池,将数据包装成一个runnable。

public void postToMainThread(Runnable runnable) {
        mDelegate.postToMainThread(runnable);
    }
private ArchTaskExecutor() {
        mDefaultTaskExecutor = new DefaultTaskExecutor();
        mDelegate = mDefaultTaskExecutor;
    }

实际是调用DefaultTaskExecutor的postToMainThread(),

public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = createAsync(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }

最终创建一个主线程的handler。

从上面可知,两个方法最终走的还是setValue(),先判断是否在主线程,然后调用dispatchingValue()进行数据分发。

void dispatchingValue(@Nullable ObserverWrapper initiator) {
        ////如果当前正在分发,则分发无效,return
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        //标记正在分发
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
            //observerWrapper不为空,使用considerNotify()通知真正的观察者
                considerNotify(initiator);
                initiator = null;
            } else {
            //observerWrapper为空,遍历通知所有的观察者
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

里面含有两个变量,mDispatchingValue表示是否正在分发,mDispatchInvalidated表示是否分发无效。

private void considerNotify(ObserverWrapper observer) {
        //observer是否是活跃状态,不是则返回
        if (!observer.mActive) {
            return;
        }
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //observer的最后版本号如果大于mVersion,表明不是最新数据,则直接return,反之则将mVersion赋值给observer的最后版本号
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //回调onChanged()
        observer.mObserver.onChanged((T) mData);
    }

回调成功之后,则在下面进行UI设置。

myViewModel.getInfo().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textView.setText(s);
            }
        });

下面我们来看observe,看它是怎么设置观察者的?

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

将传进来的owner和observer封装成一个LifecycleBoundObserver对象,为Lifecycle添加一个观察者。下面来看一下Lifecycle是什么东西。

public abstract class Lifecycle {
    //添加观察者
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
    //移除观察者
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    //获取当前状态
    public abstract State getCurrentState();

//生命周期事件,对应Activity生命周期方法
    public enum Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY  //可以响应任意一个事件
    }
    
    //生命周期状态. (Event是进入这种状态的事件)
    public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;

        //判断至少是某一状态
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }

1、Lifecycle 使用两种主要枚举跟踪其关联组件的生命周期状态:

2、Event,生命周期事件,这些事件对应Activity/Fragment生命周期方法。
State,生命周期状态,而Event是指进入一种状态的事件。

而Event与State的关系为:

public State getTargetState() {
            switch (this) {
                case ON_CREATE:
                case ON_STOP:
                    return State.CREATED;
                case ON_START:
                case ON_PAUSE:
                    return State.STARTED;
                case ON_RESUME:
                    return State.RESUMED;
                case ON_DESTROY:
                    return State.DESTROYED;
                case ON_ANY:
                    break;
            }
            throw new IllegalArgumentException(this + " has no target state");
        }

也就是通过添加一个观察者,然后根据在不同的生命周期状态做对应的事情。

下面我们来看下LifecycleBoundObserver:

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

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }
        
        //状态至少为STARTED状态
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        
        //如果当前状态为DESTROYED则直接移除观察者,并返回
        //如果当前状态与前面的状态不一致,进行状态切换
        @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);
        }
    }

状态切换

void activeStateChanged(boolean newActive) {
            //活跃状态 未发生变化时,不会处理。
            if (newActive == mActive) {
                return;
            }
          
            mActive = newActive;
            changeActiveCounter(mActive ? 1 : -1);
            //活跃则进行分发
            if (mActive) {
                dispatchingValue(this);
            }
        }
void changeActiveCounter(int change) {
        int previousActiveCount = mActiveCount;
        mActiveCount += change;
        if (mChangingActiveState) {
            return;
        }
        mChangingActiveState = true;
        try {
            while (previousActiveCount != mActiveCount) {
                boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
                boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
                previousActiveCount = mActiveCount;
                if (needToCallActive) {
                    onActive();
                } else if (needToCallInactive) {
                    onInactive();
                }
            }
        } finally {
            mChangingActiveState = false;
        }
    }

mActiveCount == 0 是指 LiveData 的活跃观察者数量。活跃的观察者数量 由0变为1、由1变为0 会分别调用LiveData的 onActive()、onInactive()方法。这就是前面提到的扩展使用的回调方法。

相关文章

网友评论

      本文标题:LiveData源码分析

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