Android 架构组件 —— Lifecycle-aware

2018-01-04  本文已影响51人  佐以言

本文将对Lifecycle-aware Components三大组件之一的LiveData进行分析。
首先,分析一下LiveData类的结构:

LiveData类结构
可以看出,LiveData给出的方法主要分为以下两类:

添加删除observer

添加observer有两个方法

  1. observeForever(@NonNull Observer<T> observer)
  2. observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer)
    方法一是将一个生命周期不会变化(保持Lifecycle.Event.ON_RESUME状态)的LifecycleOwner作为参数调用的方法二:
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
    if (owner.getLifecycle().getCurrentState() == DESTROYED) {
        // 进入DESTROYED状态无需继续
        return;
    }
    LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
    LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
    if (existing != null && existing.owner != wrapper.owner) {
        throw new IllegalArgumentException("Cannot add the same observer"
                + " with different lifecycles");
    }
    if (existing != null) {
        return;
    }
    owner.getLifecycle().addObserver(wrapper);
}

class LifecycleBoundObserver implements GenericLifecycleObserver {
    public final LifecycleOwner owner;
    public final Observer<T> observer;
    public boolean active;
    public int lastVersion = START_VERSION;

    LifecycleBoundObserver(LifecycleOwner owner, Observer<T> observer) {
        this.owner = owner;
        this.observer = observer;
    }

    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(observer);
            return;
        }
        // immediately set active state, so we'd never dispatch anything to inactive
        // owner
        activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
    }

    void activeStateChanged(boolean newActive) {
        if (newActive == active) {
            return;
        }
        active = newActive;
        boolean wasInactive = LiveData.this.mActiveCount == 0;
        LiveData.this.mActiveCount += active ? 1 : -1;
        if (wasInactive && active) {
            onActive();
        }
        if (LiveData.this.mActiveCount == 0 && !active) {
            onInactive();
        }
        if (active) {
            dispatchingValue(this);
        }
    }
}

首先将observer封装成一个LifecycleBoundObserver对象添加到mObservers中去,和前面介绍的LifecycleRegistry如出一辙,之后将封装后的observer同时注册到对应的LifecycleOwner中去,此时依据上节内容,LifecycleRegistry会将LifecycleBoundObserver进行进一步封装成为ObserverWithState,在生命周期发生变化时,通过调用dispatchEvent(LifecycleOwner owner, Event event)方法通知observer生命周期变更,从而让LifecycleBoundObserver感知生命周期,在DESTROYED状态下自动移除。

删除observer与添加逻辑相同,只是多了一步将observer激活状态改为false,对LiveData内部统计数据(mActiveCount)进行更改。

LiveData值的刷新

LiveData提供了两种方法对其进行赋值:

setValue(T value)

首先先对主线程赋值进行一个了解:

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

private void dispatchingValue(@Nullable LifecycleBoundObserver initiator) {
    if (mDispatchingValue) {
        mDispatchInvalidated = true;
        return;
    }
    mDispatchingValue = true;
    do {
        mDispatchInvalidated = false;
        if (initiator != null) {
            considerNotify(initiator);
            initiator = null;
        } else {
            for (Iterator<Map.Entry<Observer<T>, LifecycleBoundObserver>> iterator =
                    mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                considerNotify(iterator.next().getValue());
                if (mDispatchInvalidated) {
                    break;
                }
            }
        }
    } while (mDispatchInvalidated);
    mDispatchingValue = false;
}

private void considerNotify(LifecycleBoundObserver observer) {
    if (!observer.active) {
        return;
    }

    if (!isActiveState(observer.owner.getLifecycle().getCurrentState())) {
        observer.activeStateChanged(false);
        return;
    }
    if (observer.lastVersion >= mVersion) {
        return;
    }
    observer.lastVersion = mVersion;
    //noinspection unchecked
    observer.observer.onChanged((T) mData);
}

主要方法在dispatchingValue(@Nullable LifecycleBoundObserver initiator)中:

  1. mDispatchingValue -> true代表之前有值刷新尚未广播完成,将mDispatchInvalidated改为true,为false则直接向下进行;
  2. 将mDispatchingValue设为true表示正在广播,随后判断是对单个observer进行通知或者对所有监听此项的observer进行通知。此时若有新值需要广播,则在对所有监听此项observer进行通知时直接退出重新遍历发送最新值。
    considerNotify(LifecycleBoundObserver observer)方法则是根据当前项的激活状态决定是移除observer还是将值变化通知对应observer进行改变。

postValue(T value)

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;
        }
        //noinspection unchecked
        setValue((T) newValue);
    }
};

postValue(T value)则是先暂时将新值保存,随后将具体调用setValue方法post到一个依附于主线程的Handle中去,通过Handle达到线程切换目的从而通知值刷新。

使用

LiveData使用时主要是使用子类MutableLiveData,这个子类实现了Livedata并公开了两个赋值方法。

小结

LiveData的工作流程在有了之前LifecycleRegistry的分析之后变得很清晰:主要是将observer封装后存储,并依托LifecycleRegistry根据生命周期和自身值变化达到刷新通知observer进行刷新目的。

上一篇 下一篇

猜你喜欢

热点阅读