JetPack之LiveData2.2.0源码分析

基于:

api "androidx.lifecycle:lifecycle-extensions:2.2.0"
api "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"

1. 为LiveData添加观察者observe

//liveData添加观察者observe
viewModel.liveData.observe(this, Observer {
})

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    assertMainThread("observe");
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // 如果LifecycleOwner处于onDestroy状态就不处理
        return;
    }
    //进行一层包装,使得观察者observer可以感知到activity的生命周期发生变化
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing != null && !existing.isAttachedTo(owner)) {
        //liveData不能添加具有不同生命周期的同一观察者
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    //注意:当添加wrapper后,马上就会执行LifecycleBoundObserver的onStateChanged()方法
    owner.getLifecycle().addObserver(wrapper);
}

1.1  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() {
        //判断activity是否处于活跃状态:当前状态是否大于等于STARTED, 满足条件的只有STARTED与RESUMED
        //也就是当activity处于onStart、onResume、onPause的时候,是活跃状态
        return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source,
            @NonNull Lifecycle.Event event) {
        // 由于实现了LifecycleEventObserver,当activity生命周期发生改变,到onDestroy后,就自动进行了移除       
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        //每次生命周期状态发生改变,都会执行这里。
        activeStateChanged(shouldBeActive());
    }

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

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

然后就来到了activeStateChanged(shouldBeActive());

void activeStateChanged(boolean newActive) {
    if (newActive == mActive) {
        return; //活跃性状态一致 被return
    }
    mActive = newActive;
    boolean wasInactive = LiveData.this.mActiveCount == 0;
    LiveData.this.mActiveCount += mActive ? 1 : -1;
    if (wasInactive && mActive) {
        onActive();//当liveData的活动观察者的数量从0变为1时调用。
    }
    //注意:一个liveData可以添加多个观察者,所以每个观察者都对应一个该方法,但是LiveData.this.mActiveCount是公共的
    if (LiveData.this.mActiveCount == 0 && !mActive) {
        onInactive();//当liveData的活动观察者的数量从1变为0时调用。
    }
    if (mActive) {
        dispatchingValue(this); //只有mActive为true 并且newActive为false的时候才能走入这里 ,也就是从非活跃状态到活跃状态
    }
}

//接着看事件分发
void dispatchingValue(@Nullable ObserverWrapper initiator) {
    //防止重复分发相同的内容
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;//开始发送事件 赋值为true
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            //只处理当前Observer,因为每个Observer 都会单独走一遍dispatchingValue方法
            considerNotify(initiator);
            initiator = null;
        } else {
            //当使用setValue的时候, initiator为null。 遍历liveData的所有观察者,准备执行对应的回调
            for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;//发送完毕后,还原
}

private void considerNotify(ObserverWrapper observer) {
    if (!observer.mActive) {
        return;
    }
    if (!observer.shouldBeActive()) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.mLastVersion >= mVersion) {
        return;
    }
    observer.mLastVersion = mVersion;
    observer.mObserver.onChanged((T) mData);//数据回调到观察者
}

2. 版本号mVersion的作用:

当把LifecycleBoundObserver添加到LifecycleOwner后,会马上执行LifecycleBoundObserver的onStateChanged()方法,使得跟activity的生命周期状态同步,
接着也就会执行activeStateChanged() -> dispatchingValue() -> considerNotify() 但此时observer.mLastVersion不会大于mVersion,所以被mVersion拦截,就不会执行onChanged()方法了

3. LiveData数据覆盖问题 

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

当activity不在活跃状态时,多次调用liveData.setValue方法,会被observer.shouldBeActive()拦截,而mData会等于最后一次setValue的值,当activity由非活跃变成活跃状态后,会走到LifecycleBoundObserver -> onStateChanged -> activeStateChanged -> dispatchingValue ,再将mData回调出去,也就是只有最后一次setValue的值被观察者拿到了。

对于postValue

protected void postValue(T value) {
    boolean postTask;
    synchronized (mDataLock) {
        postTask = mPendingData == NOT_SET;
        mPendingData = value; //保存需要发送的值
    }
    if (!postTask) {
        return; //如果mPostValueRunnable没走完,后面再调用postValue,在这里进行拦截,而mPendingData记录的最后一次的数据
    }
    //需要经过handler进行一次线程的切换,然后再调用setValue。(这里就要看handler的post执行原理了)
    ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}

现象如下:

//在点击事件中执行下面方法(此时activity是活跃状态)
btn.setOnClickListener {
    viewModel.liveDataTest()
}

viewModel.liveData.observe(this, Observer {
    Log.e("tag", " it = $it")
})

fun liveDataTest() {
    viewModelScope.launch {
        withContext(Dispatchers.IO) {
            liveData.postValue("post的数据1")
            liveData.postValue("post的数据2")
            liveData.postValue("post的数据3")
        }
    }
    liveData.setValue("set的数据1")
    liveData.setValue("set的数据2")
}

//输出日志:
it = set的数据1
it = set的数据2
it = post的数据3

 

4. 使用observeForever()的方式添加观察者,避免发送的data被覆盖

//使用observeForever的方式添加观察者时,内部的包装内为AlwaysActiveObserver
viewModel.liveData.observeForever {
}

private class AlwaysActiveObserver extends ObserverWrapper {

    AlwaysActiveObserver(Observer<? super T> observer) {
        super(observer);
    }

    @Override
    boolean shouldBeActive() {
        //LifecycleBoundObserver的shouldBeActive受activity的状态影响,这里直接返回true,也就不管activity处于什么状态,都会发送data了
        return true;
    }
}

由于使用了observeForever后,AlwaysActiveObserver不能感知activity的生命周期,也就不能像LifecycleBoundObserver一样帮我们removeObserver()了,所以需要我们自己手动调用removeObserver()方法去解除绑定

LiveData源码总结

  • LiveData的观察者可以联动生命周期, 也可以不联动。在联动生命周期时,会自动在 DESTROYED 的状态下移除 Observer ,取消订阅,所以不用担心内存泄露;
  • LiveData的观察者只能与一个LifecycleOwner绑定, 否则会抛出异常。而一个 owner 可以绑定多个 Observer 实例;
  • LiveData 跟 LifecycleOwner 绑定,能感知生命周期变化,并且只会在 LifecycleOwner 处于 Active 状态(STARTED/RESUMED)下通知数据改变;如果数据改变发生在非 active 状态,数据会变化,但是不发送通知,等 owner 回到 active 的状态下,再发送通知;
  • 使用observeForever()方法,会注意AlwaysActiveObserver对象,意味着给定的观察者将接收所有事件,并且永远不会被自动删除,不管在什么状态下都能接收到数据的更改通知
  • LiveData 利用版本管理、绑定 Lifecycle 确保了只会发送最新的数据给 active 状态下的 Observer

 

posted @ 2020-07-09 16:25  ts-android  阅读(276)  评论(0编辑  收藏  举报