Lifecycle + LiveData + ViewModel源码解析

一 简介

Lifecycle 是 Jetpack 整个家族体系内最为基础的内容之一,为上层的LiveData、ViewModel等等更上层的组件提供监听 Activity、Fragment、Service、甚至 Process 的生命周期变化的统一方式。
LiveData 是 Jetpack 家族的一种响应式开发框架,类似框架有还RxJava等。以数据驱动的方式更新UI,并且由于其基于Livecycle,能够感知组件生命周期变化,只会更新活跃的组件的状态,并在组件销毁时能自动解除对该组件的监听。
ViewModel: Activity或Fragment支持以数据以ViewModel的形式存储在内部,于是ViewModel常常作为组件相关的多个LiveData的存储载体。ViewModel 里面的数据不会因为屏幕的旋转或者其他配置(比如切换到多窗口模式)而丢失。

二 Lifecycle

前边提到Lifecycle提供了程序监听组件(后边统一以Activity组件来展开介绍)的接口

public abstract class Lifecycle {

    public abstract void addObserver(@NonNull LifecycleObserver observer);

    public abstract void removeObserver(@NonNull LifecycleObserver observer);
}

程序员可以自定义实现LifecycleObserver来监听activity的生命周期

Lifecycle是一个抽象类,它的唯一实现类为LifecycleRegister。查看FeagmentActivity的getLifecycle()方法,返回的就是LifecycleRegister的对象

public Lifecycle getLifecycle() {
    // Instead of directly using the Activity's Lifecycle, we
    // use a LifecycleRegistry that is nested exactly outside of
    // when Fragments get their lifecycle changed
    // TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver
    return mFragmentLifecycleRegistry;
}

LifecycleRegister内部的mObserverMap字段保存了所有监听该Activity(LifecycleOwner)的观察者

private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
        new FastSafeIterableMap<>();

下边分析下Lifecycle如何完成监听activity的生命周期变化:
以FragmentActivity的onCreate()方法为入口:

protected void onCreate(@Nullable Bundle savedInstanceState) {
   // ...

    super.onCreate(savedInstanceState);
    mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);

    // ...
}

可以看到会调用LifecycleRegister的handlerLifecycleEvent()方法。
给出handlerLifecycleEvent()的调用链:
handlerLifecycleEvent() -> moveToState() -> sync() -> forwardPass() -> LifecycleEventObserver.dispatchEvent() -> LifecycleEventObserver.onStateChanged()

  • LifecycleRegister的handlerLifecycleEvent(Lifecycle.Event)传递一个Lifecycle.Event,并根据这个Event对象更改自己的state。
  • moveToState()修改LifecycleRegister的 state,调用sync()
  • sync()负责通知observer,(以forwardPass()为例)
  • forwardPass()遍历所有的Observer,一一通知
  • LifecycleEventObserver.dispatchEvent()是单个observer对通知进行处理
  • 最后触发我们LifecycleEventObserver.onStateChanged()来完成回调。
    注:LifecycleEventObserver是LifecycleObserver的一个子接口,其onStateChanged()感知被监听组件的所有生命周期变化

三 LiveData

LiveData的简单使用这边不做介绍,需先了解其简单实用再向下看。
LiveData可以认为是我们要存储的对象的一个封装

public abstract class LiveData<T> {
    public T getValue() {
        Object data = mData;
        if (data != NOT_SET) {
            //noinspection unchecked
            return (T) data;
        }
        return null;
    }

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

通过其getValue()和和setValue()方法可以看出这一点。
既然将我们存储的对象封装起来,必然要有其好处。使用LiveData封装起来数据的好处也即是前边提到的 其封装的数据的变化能够被监听(数据驱动视图的基础),并且能够感知组件生命周期。

3.1 LiveData如何实现感知组件生命周期

和前边的Lifecycle一样,LiveData也能被Observer监听。不过LiveData的Observer的类型为androidx.lifecycle.Observer,其接口只有一个方法,onChanged(),方法在LiveData所封装的数据变化时被回调。

public interface Observer<T> {
    /**
     * Called when the data is changed.
     * @param t  The new data
     */
    void onChanged(T t);
}

一个LiveData能被多个Observer监听,其内部保存了所有监听该LiveData数据的观察者(可以看到类似于前边提到LifecycleRegister)

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

从LiveData.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);
}

通过

LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);

这句代码可以看到,LiveData将owner(LiveData内部数据所在的组件)和observer包装成了一个LifecycleBoundObserver对象(warpper)。然后将这个warpper保存在内部的mObservers中

ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

最后给组件的Lifecyle也注册此观察者

owner.getLifecycle().addObserver(wrapper);

先来分析下LifecycleBoundObserver这个类。

class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {

    @Override
    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            removeObserver(mObserver);
            return;
        }
        activeStateChanged(shouldBeActive());
    }

}

LifecycleBoundObserver继承自ObserverWarpper、实现了GenericLifecycleObserver接口,GenericLifecycleObserver是LifecycleEventObserver的子接口,所以其实现LifecycleEventObserver的onStateChanged()方法,具有了监听组件生命周期的能力。
查看onStateChanged()方法的逻辑,当组件(LifecycleOwner)的状态变为DESTROYED时,执行removeObserver(),自动解绑当前观察者。自此可以看到LiveData内部能够感知组件生命周期,能够自动解绑观察者,避免内存泄漏。

3.2 LiveData如何实现监听数据的变化

既然要看LiveData如何实现监听数据的变化,首先就得看看如何改变LiveData的数据,LiveData.setValue()
从LiveData.setValue()方法入手

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

接着进入dispatchingValue()方法

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

由于传入的参数initiator为null,我们直接看initiator ==null 的分支。会遍历该LiveData的所有观察者,逐一调用considerNotify()方法。

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);
}

可以看到最后一句

observer.mObserver.onChanged((T) mData);

回调了LiveData观察者的onChanged()方法,我们即可以在此回调中更新与该数据绑定的相关UI。

四 ViewModel

4.1 ViewModelStore

说到ViewModel首先来看看Activity对ViewModel的支持。

public class ComponentActivity extends androidx.core.app.ComponentActivity implements ViewModelStoreOwner{
    private ViewModelStore mViewModelStore;
}

ComponentActivity实现了ViewModelOwner接口,并内部持有ViewModelStore对象
查看ViewModelStore对象

public class ViewModelStore {

    private final HashMap<String, ViewModel> mMap = new HashMap<>();

    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = mMap.put(key, viewModel);
        if (oldViewModel != null) {
            oldViewModel.onCleared();
        }
    }

    final ViewModel get(String key) {
        return mMap.get(key);
    }

    Set<String> keys() {
        return new HashSet<>(mMap.keySet());
    }

    /**
     *  Clears internal storage and notifies ViewModels that they are no longer used.
     */
    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.clear();
        }
        mMap.clear();
    }
}

可以看到ViewModelStore对象内部简单通过一个HashMap保存了与此Activity关联的所有ViewModel。

4.2 ViewModelProviders.of(activity).get(ViewModel.class)

ViewModelProviders.of(activity).get(ViewModel.class);

此调用用于获取同一个activity内部的的ViewModel对象,可以方便的实现在该activity的任何组件内获得该activity的共享的ViewModel,进而可以通过此特性很方便实现activty内部的组件通信。
源码也相对简单

ViewModelProviders.of(activity)

会获得一个ViewModelProvider对象,

ViewModelProvider.get(ViewModel.class);

会查找该acitvity的viewModelStore对象找到对应的ViewModel

一个ViewModel相关的疑问解答

  1. ViewModel的作用是什么,看起来单独的LiveData已经就拥有了根据数据变化自动更新UI的功能,并也能完成在LifecycleOwner销毁时自动removeObserver的功能。难道仅仅是MVVM的一个部分,看起来继承ViewModel的意义就不大了
    a. ViewModel提供了一种访问数据的统一方式,在整个Activity内部的任何组件都能直接获取整个Activity的共享数据。
ViewModelProviders.of(getActivity()).get(XXXModel.class)

也可进一步理解为Activity提供了ViewModelStore而没有提供LiveDataStore,所以才导致要使用ViewModel
b. Activity有对ViewModel的恢复机制,在Activity销毁重建后仍然可以获得原来的ViewModel内容

相关博客参考

Lifecycle源码解析:https://juejin.im/post/6847902220755992589#heading-13
LiveData源码解析:https://juejin.im/post/6844903796657782791
ViewModel源码解析:https://juejin.im/post/6844904169401221134

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值