Android 架构组件 —— Lifecycle-aware Components [三]

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

LiveData类结构

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

  • 添加删除observer
  • 更新本身存储的数据
    接下来将对这两个方面入手分析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)(主线程赋值)
  • postValue(T value)(子线程赋值)

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进行刷新目的。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言: 作为一名移动互联网App研发人员,在实际项目的研发过程中,保质保量高效率,方便快捷,同时方便开发者之间的互...
    Yagami3zZ阅读 4,710评论 1 9
  • 前言 系列文章 Android Architecture Component之Lifecycle-Aware Co...
    Jason骑蜗牛看世界阅读 3,583评论 3 20
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,127评论 19 139
  • 示例应用程序 使用LiveData的优点 使用LiveData对象创建LiveData对象观察LiveData对象...
    yyg阅读 5,895评论 5 7
  • 吴贤碧 我以浅坐的姿态 着一袭白裙 以品茶的借口 在湖边等了又等 终在秋天泛红的那片红叶里 等来翩然而至的你 相思...
    闲笔阅读 987评论 0 1