Jetpack介绍之LiveData分析

LiveData简介

它是一个绑定了给定的生命周期的数据持有类,每一个注册的observer都和一个生命周期LifecycleOwner串联在一起,只有在LifecycleOwner在活跃状态时才会通知修改数据。

1. 使用分析

  1. 可以使用observeForever,这样代表任何时候都是活跃状态,所以需要手动的removeObserver才可以;
  2. 另一种可以使用observe,它可以和当前的生命周期绑定,例如activitiesfragments中,这样会在onDestory的时候自定的解绑定;
  3. LiveData本身有两个方法onActiveonInactive,可以用来释放不需要的资源
  4. 它是用来设计的在viewmodel独立持有数据,也可以解耦的方式来分享数据。

还需要看一下生命周期的状态:

状态(枚举)值从低到高介绍
DESTROYED执行ON_DESTORY之后
INITIALIZED默认初始状态
CREATED执行ON_CREATE之后,或者在ON_STOP之后
STARTED执行ON_START之后,或者在ON_PAUSE之后
RESUMED执行ON_RESUME之后

可以查看官方文档,加深对于生命周期状态的理解:

在这里插入图片描述

2. 源码分析

来看一下observer这个方法的功能:

  1. 只有在active时才会接收到数据
  2. 会自动的解绑定,在DESTROYED状态的时候
  3. 如果在inactive过程中改变了数据,从inactiveactivive会接收到最新一次的可用数据
  4. 如果在DESTROYEDobserver会自动忽略此次调用
  5. 如果给定的所有者、观察者已经在列表中,则忽略调用。
  6. 如果观察者已经在另一个所有者的列表中,LiveData会抛出一个异常
    分析一下源码:
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    assertMainThread("observe");
    //--4.如果在`DESTROYED`时`observer`会自动忽略此次调用
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // ignore
        return;
    }
    //--1.进行和声明周期的绑定
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    //--6. 如果观察者已经在另一个所有者的列表中,LiveData会抛出一个异常
    if (existing != null && !existing.isAttachedTo(owner)) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    //--5. 如果给定的所有者、观察者已经在列表中,则忽略调用。
    if (existing != null) {
        return;
    }
    owner.getLifecycle().addObserver(wrapper);
}

LifecycleBoundObserver是一个继承了ObserverWrapper和实现了GenericLifecycleObserver接口的类

  • ObserverWrapper:持有当前的observer,提供数据更新方法
  • GenericLifecycleObserver:代表的是生命周期变化,会有回调,生命周期状态改变,再调用ObserverWrapper提供的activeStateChanged方法进行对应的数据变化

我们来看一下LifecycleBoundObserver中具体的方法:

public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
    //--2.会自动的解绑定,在DESTROYED状态的时候
    if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
        removeObserver(mObserver);
        return;
    }
    activeStateChanged(shouldBeActive());
}

从上述的源码分析可以看到,我们常用的方法observer对于传递进来的参数,使用LifecycleBoundObserver进行了绑定,然后存储在mObservers,进行了一些合法性的校验

private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers = new SafeIterableMap<>();

最终还是会到

owner.getLifecycle().addObserver(wrapper);

那么我们就有必要看看这行代码到底干了什么了。

LiveData的分析离不开使用Lifecycle,所以先看一下Lifecycle吧,LifecycleObserver是一个一对多的关系,我们可以有很多的Observer来监听当前的Lifecycle的状态变化
在这里插入图片描述

  1. fragmentFragmentActivity中有相应的实现,直接使用getLifecycle即可
  2. LifecycleOwner相关的生命周期方法之后,才会执行ON_CREATE,ON_START,ON_RESUME事件
  3. LifecycleOwner相关的生命周期方法之前,才会执行ON_PAUSE,ON_STOP,ON_DESTROY,例如在onStart之后执行,在onStop之前执行,这样会保证状态的正确性
  4. java7使用注解方式,可以接受参数,第一个必须是LifecycleOwner,在java8通过实现DefaultLifecycleObserver这个来做

具体的实现类是LifecycleRegistry,我们来看一下关键的方法
addObserver,将当前的observer和生命周期状态绑定起来,具体的实现类是ObserverWithState,持有LifecycleBoundObserver和当前的生命周期状态;

@Override
public void addObserver(@NonNull LifecycleObserver observer) {
    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
    //--1.将当前的observer和生命周期状态绑定
    //非DESTROYED时,都为INITIALIZED状态
    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);

    if (previous != null) {
        return;
    }
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        // it is null we should be destroyed. Fallback quickly
        return;
    }
    // 判断是否还没有处理完就重入此方法
    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
    // 计算当前的状态,取mObserverMap的observer前一个状态和INITIALIZED进行比较选最小的状态
    State targetState = calculateTargetState(observer);
    mAddingObserverCounter++;
    //如果是在onCreate中注册的话,那么mState是INITIALIZED,不会进入这一循环当中;
    //但是如果我们是在onStart中调用的addObserver的话,那么tartgetState会大于INITIALIZED,就会进入次循环来更新当前的observer的值;
    //也就是说我们无论在哪里调用的addObserver,只要在生命周期回调的时候就会有对应的方法被触发看是否需要更新成最近一次的值
    while ((statefulObserver.mState.compareTo(targetState) < 0
            && mObserverMap.contains(observer))) {
        pushParentState(statefulObserver.mState);
        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
        popParentState();
        // mState / subling may have been changed recalculate
        targetState = calculateTargetState(observer);
    }

    if (!isReentrance) {
        // we do sync only on the top level.
        sync();
    }
    mAddingObserverCounter--;
}

具体看一下ObserverWithState这个类,持有Observer和调用addObserver时的状态

static class ObserverWithState {
    State mState;
    GenericLifecycleObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.getCallback(observer);
        mState = initialState;
    }

    //当event进行改变时会调用此方法
    void dispatchEvent(LifecycleOwner owner, Event event) {
        //生命周期改变时会调用此方法,最终到LiveData的activeStateChanged方法中,用来更新数据的
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        mLifecycleObserver.onStateChanged(owner, event);
        //重新设置当前的状态
        mState = newState;
    }
}

LifecycleRegistry中有一个handleLifecycleEvent方法,当绑定了生命周期的事件后,只要有生命周期的事件改变了,就会调用此方法修改当前的mState,这样结合addObserver中的方法,如果注册的状态小于当前的状态,那么就会更新数据了,这样的话看着更清楚。我们重点看一下生命周期改变的sync方法

private void sync() {
    LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
    if (lifecycleOwner == null) {
        Log.w(LOG_TAG, "LifecycleOwner is garbage collected, you shouldn't try dispatch "
                + "new events from it.");
        return;
    }
    while (!isSynced()) {
        mNewEventOccurred = false;
        // no need to check eldest for nullability, because isSynced does it for us.
        if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
            //后退策略,生命周期从onPause->onStop->onDestory时会走这个
            backwardPass(lifecycleOwner);
        }
        Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
        if (!mNewEventOccurred && newest != null
                && mState.compareTo(newest.getValue().mState) > 0) {
            //前进策略,生命周期从onCreate->onStart->onResume时会走这个
            forwardPass(lifecycleOwner);
        }
    }
    mNewEventOccurred = false;
}

只看一个就好了,我们看一下forwardPass方法:

private void forwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            //看着和addObserver的方法一样的,就是现在的生命周期状态变化了,所以要通过LifecycleObserver更新了
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}

好了,注册一个observer的过程我们清楚了,我们画一下对应的函数调用图

INITIALIZED状态时进行注册的,也就是在onCreate中进行的observer,函数调用图:
在这里插入图片描述

INITIALIZED状态之后再进行注册的,也就是不在onCreate中进行observer,而是在onStart等之后的函数调用图:
在这里插入图片描述

Lifecycle生命周期进行变换时的函数调用:(以生命周期向前为例,例如onCreate->onStart,onStart->onResume)
在这里插入图片描述

我们再看一下更新数据的逻辑,直接看setValue方法,

@MainThread
protected void setValue(T value) {
    assertMainThread("setValue");
    //更新版本
    mVersion++;
    //当前最新的值
    mData = value;
    dispatchingValue(null);
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        //initiator为null,所以会走到else中
        if (initiator != null) {
            //当生命周期有变化时会走到这里更新数据
            considerNotify(initiator);
            initiator = null;
        } else {
            //会将注册的所有observer进行遍历,然后通知当前修改
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

最后我们看到,在considerNorify用来更新observer的数据

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;
    //noinspection unchecked
    // 实际更新数据的地方
    observer.mObserver.onChanged((T) mData);
}

我们使用setValue更新数据时的函数调用:
在这里插入图片描述

以上就是对于LiveData的源码分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值