jetpack源码-LiveData/ViewModel篇

1,152 阅读15分钟

1 前言

谷歌I/O 发布了一系列辅助android开发者的实用工具,合称Jetpack,其通过提供现代化应用架构以及提供强健的向后兼容能力等方式,让开发者能够快速、轻松地创造拥有卓越性能的高质量应用。本系列文章会介绍一下5个方面:

  • arch:线程管理、灵活增加删除的map 链接
  • 生命周期lifecycle 链接
  • 数据驱动:livedata、viewmodel 链接
  • 数据库Room 链接
  • 后台作业调度

本文介绍LiveData、ViewModel以及SaveState框架,主要涉及以下三方引用:

  1. lifecycle-livedata:2.2.0、lifecycle-livedata-core:2.3.0

    主要类LiveData、ComputableLiveData;利用观察者模式达到数据驱动的效果,监听者利用lifecycle架构可以感知生命周期

  2. savedstate:1.1.0

    提供了activity/fragment中横竖屏切换以及异常销毁时数据保存机制

  3. lifecycle-viewmodel:2.3.0、lifecycle-viewmodel-savedstate:2.3.0

    提供了vm角色基础模型,并提供vm数据在横竖屏切换以及异常销毁时保存机制

2 LiveData库

LiveData架构存在与两个库,其中类图如下 livedata-类图.png

  1. LiveData:抽象类,livedata的核心类,实现了数据的改变与获取以及数据变化监听
  2. MutableLiveData:LiveData的实现类
  3. ComputableLiveData:抽象类, LiveData装饰类,内部内聚数据变化功能
  4. Observer:接口,数据变化监听者
  5. MediatorLiveData:LiveData实现类,也是livedata以及其监听对象的管理者管理者

这里主要介绍LiveData、ComputableLiveData、MediatorLiveData类

2.1 LiveData抽象类

内容主要涉及数据改变、监听存储、事件分发

2.1.1 监听存储

监听的注册和解绑根据是否有生命周期感知能力而有所不同

生命周期感知

注册

    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对象并保存起来,并且注册到生命周期中;LifecycleOwner为具有生命周期的对象

解绑

    public void removeObservers(@NonNull final LifecycleOwner owner) {
        assertMainThread("removeObservers");
        for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
            if (entry.getValue().isAttachedTo(owner)) {
                removeObserver(entry.getKey());
            }
        }
    }

通过判断是否对生命周期进行绑定,进而通过removeObserver(@NonNull final Observer<? super T> observer)来移除每一个监听者

无生命周期感知

注册

    public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }

监听者装饰为AlwaysActiveObserver对象,并存储

解绑

   public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }
        removed.detachObserver();
        removed.activeStateChanged(false);
    }

移除监听者,并进行取消生命周期监听(无感知则无处理),并改变活跃个数

2.1.2 数据变化

两个函数提供了数据变化提交调用postValue、setValue;postValue方法为异步提交,最后也是通过setValue来达到效果的;

postValue方法

     protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

数据变化采用了锁机制,达到异步安全;首先修改中间数据对象,并提交到主线程进行更新;mPendingData为NOT_SET时说明数据未发生变化,不为NOT_SET,说数据正在发生变化还未结束

任务对象

private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };

采用锁机制,获取数据最新内容;并通过setValue方法进行设置;和异步提交采用同一锁进行同步,并采用中间变量标志状态,减少锁持有时常,并保证异步提交数据后,主线程确定数据变化后不会在更新过程中数据变动

setValue方法

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

记录版本、改变数据,并通过dispatchingValue进行数据变化分发;

2.1.3 分发

活跃状态分发、以及数据值分发

活跃状态

    void changeActiveCounter(int change) {
        int previousActiveCount = mActiveCount;
        mActiveCount += change;
        if (mChangingActiveState) {
            return;
        }
        mChangingActiveState = true;
        try {
            while (previousActiveCount != mActiveCount) {
                boolean needToCallActive = previousActiveCount == 0 && mActiveCount > 0;
                boolean needToCallInactive = previousActiveCount > 0 && mActiveCount == 0;
                previousActiveCount = mActiveCount;
                if (needToCallActive) {
                    onActive();
                } else if (needToCallInactive) {
                    onInactive();
                }
            }
        } finally {
            mChangingActiveState = false;
        }
    }

活跃状态处理存在与监听注册、解绑或者生命周期感知销毁时,进行处理

  1. onActive()调用出现在从没有活跃的监听者到出现活跃监听者
  2. onInactive()调用出现在从有活跃的监听到没有活跃的监听者
  3. 这里预防了嵌套调用,采用活跃数量、以及是否正在处理来解决;处理状态决定后面流程只执行一次,循环判断当前活跃监听数量与之前活跃数量不同,来标志处理流程中是否又发生了变化,进而达到数据处理符合最终结果

数据分发

处理存在与监听注册、生命周期状态变化、数据改变;其中生命周期变化,只会从不活跃到活跃才会发生;而监听注册只在注册时处于活跃状态才会分发

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

而具体分发时依据传参不同来表明场景不同,参数为空,表示数据发生变化,通知所有监听者;不为空只通知当前监听者;但是这里面也存在嵌套场景;采用下面两个变量进行处理

  1. mDispatchingValue表明是否在正在进行分发
  2. mDispatchInvalidated表明分发过程状态是否再次变化
  3. 若单独分发到某个监听者时存在嵌套,置空参数,来处理数据分发者漏掉的情况
  4. 分发所有监听者,发生嵌套时,终止当前迭代,重新迭代,减少无效分发或者漏掉分发对象

considerNotify方法进行对每个监听者分发,通过状态的活跃状态、数值版本,来避免不必要的分发;

    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.2 ComputableLiveData类

内部包含了LiveData实现类;抽象方法compute,进行数据计算;外部只需监听即可;触发计算时机有两个,调用invalidate方法、或者Livedata的onActivie方法触发(更具体场景见livedata类分析);

数据监听触发计算

    public ComputableLiveData() {
        this(ArchTaskExecutor.getIOThreadExecutor());
    }

    public ComputableLiveData(@NonNull Executor executor) {
        mExecutor = executor;
        mLiveData = new LiveData<T>() {
            @Override
            protected void onActive() {
                mExecutor.execute(mRefreshRunnable);
            }
        };
    }

构造器方法,默认数据执行在Arch的IO线程池中,LiveData实现对象,在onActive中执行mRefreshRunnable任务

invalidate方法触发计算

在主线程中执行mInvalidationRunnable任务

   final Runnable mInvalidationRunnable = new Runnable() {
        @MainThread
        @Override
        public void run() {
            boolean isActive = mLiveData.hasActiveObservers();
            if (mInvalid.compareAndSet(false, true)) {
                if (isActive) {
                    mExecutor.execute(mRefreshRunnable);
                }
            }
        }
    };

    public void invalidate() {
        ArchTaskExecutor.getInstance().executeOnMainThread(mInvalidationRunnable);
    }

如果存在活跃用户,且当前处在未进行刷新状态,则异步执行计算任务

计算任务

final Runnable mRefreshRunnable = new Runnable() {
        @WorkerThread
        @Override
        public void run() {
            boolean computed;
            do {
                computed = false;
                if (mComputing.compareAndSet(false, true)) {
                    try {
                        T value = null;
                        while (mInvalid.compareAndSet(true, false)) {
                            computed = true;
                            value = compute();
                        }
                        if (computed) {
                            mLiveData.postValue(value);
                        }
                    } finally {
                        mComputing.set(false);
                    }
                }
            } while (computed && mInvalid.get());
        }
    };

compute方法可以不考虑异常,但异常时,不进行分发;其中仍然考虑了嵌套场景,也考虑并发场景;采用原子类+循环来解决并发;通过刷新状态、当前计算状态以及线程计算状态来进行循环处理

  1. mComputing:boolean原子类,原子值为false,表明计算结束或者未计算
  2. computed临时变量,用于表示本次调用的上次计算是否完毕
  3. mInvalid:boolean原子类,用来表示是否已经刷新过了,原子值为true时表明需要刷新

这里的循环很有意思,一般来讲有计算状态和刷新状态,就可以搞定,为啥还有增加个临时变量且最外层要判断invalid状态呢?

这里是接收到刷新状态,在当前线程中执行,而不必等待下个刷新任务去执行;下个任务有可能被阻塞了,减少了不及时传递的可能

2.3 MediatorLiveData类

内部实现并不复杂,这里不进行具体介绍了;这里说下其特性

  1. 本身实现了LiveData
  2. 统一管理一系列LiveData以及其监听者;这些LiveData又具有以下特性
    • 这些管理的livedata的监听者不具备生命周期感知
    • livedata的监听者有且仅有一个
    • 这些监听者是否监听取决与当前类自己的数据活跃监听者数量
    • 当前类在onActive、onInactive、监听、解绑方法中管理其存储的livedata相关的监听者的注册解绑

有这些特性可以知道,使用的场景很有意思,在Work库中被使用了;简化来说这种场景就是:一个数据被监听处理,则其它一些列的监听状态也需要跟着处理(有点流水线,机器运转工人需要干活,机器停止工人就不要干活的场景)

3 savestate库

类图如下

savedstate.png

  1. SavedStateRegistryOwner:state存储和恢复的宿主,这里主要是activity、fragment、
  2. SavedStateRegistryController:宿主对state存储和恢复的枢纽
  3. SavedStateRegistry:存储和恢复数据的主要管理者
  4. SavedStateRegistry.SavedStateProvider: 状态数据的具体提供者
  5. SavedStateRegistry.AutoRecreated:生命周期中根据状态自动执行类
  6. Recreator.SavedStateProvider:静态内部类,包权限;提供SavedStateRegistry.AutoRecreated的class的存储;暂时所知其内部只有存储SavedStateHandleController.OnRecreation类
  7. Recreator:SavedStateRegistry.AutoRecreated的class数据获取,并自动执行以及初始化

下面主要介绍SavedStateRegistryController、SavedStateRegistry、Recreator和其内部类

3.1 SavedStateRegistryController类

逻辑实现主要为存储和取出;

取出

    public void performRestore(@Nullable Bundle savedState) {
        Lifecycle lifecycle = mOwner.getLifecycle();
        if (lifecycle.getCurrentState() != Lifecycle.State.INITIALIZED) {
            throw new IllegalStateException("Restarter must be created only during "
                    + "owner's initialization stage");
        }
        lifecycle.addObserver(new Recreator(mOwner));
        mRegistry.performRestore(lifecycle, savedState);
    }

当前状态为Lifecycle.State.INITIALIZED,下个状态为Lifecycle.Event.ON_CREATE;也即activity 的onCreate、fragment的performCreate方法中调用;调用SavedStateRegistry来完成存储数据解析;Recreator中完成SavedStateRegistry.AutoRecreated的对象创建以及初始化(其实是完成了viewmodel的数据解析和设置,以便viewmodel创建时自动数据填充)

存储

    @MainThread
    public void performSave(@NonNull Bundle outBundle) {
        mRegistry.performSave(outBundle);
    }

在activity的onSaveInstanceState,fragment的performSaveInstanceState方法中执行,也即在ON_STOP之前ON_PAUSE之后

3.2 SavedStateRegistry类

其中包括SavedStateProvider管理,数据管理,AutoRecreated对象的存储

3.2.1 SavedStateProvider管理

    public void registerSavedStateProvider(@NonNull String key,
            @NonNull SavedStateProvider provider) {
        SavedStateProvider previous = mComponents.putIfAbsent(key, provider);
        if (previous != null) {
            throw new IllegalArgumentException("SavedStateProvider with the given key is"
                    + " already registered");
        }
    }

    public void unregisterSavedStateProvider(@NonNull String key) {
        mComponents.remove(key);
    }

通过集合SafeIterableMap<String, SavedStateProvider>存储以获取来达到SavedStateProvider的记录

3.2.2 AutoRecreated对象存储

public void runOnNextRecreation(@NonNull Class<? extends AutoRecreated> clazz) {
        if (!mAllowingSavingState) {
            throw new IllegalStateException(
                    "Can not perform this action after onSaveInstanceState");
        }
        if (mRecreatorProvider == null) {
            mRecreatorProvider = new Recreator.SavedStateProvider(this);
        }
        try {
            clazz.getDeclaredConstructor();
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("Class" + clazz.getSimpleName() + " must have "
                    + "default constructor in order to be automatically recreated", e);
        }
        mRecreatorProvider.add(clazz.getName());
    }

通过Recreator.SavedStateProvider把AutoRecreated类class对象加入,Recreator.SavedStateProvider构造器进行了注册了本身,以达到AutoRecreated类的存储

3.2.3 数据管理

数据以androidx.lifecycle.BundlableSavedStateRegistry.key为key值,Bundle类型数据为value进行存储;SavedStateProvider中也是存储数据的对象,其saveState方法结果为存储值

存储方法

    void performSave(@NonNull Bundle outBundle) {
        Bundle components = new Bundle();
        if (mRestoredState != null) {
            components.putAll(mRestoredState);
        }
        for (Iterator<Map.Entry<String, SavedStateProvider>> it =
                mComponents.iteratorWithAdditions(); it.hasNext(); ) {
            Map.Entry<String, SavedStateProvider> entry1 = it.next();
            components.putBundle(entry1.getKey(), entry1.getValue().saveState());
        }
        outBundle.putBundle(SAVED_COMPONENTS_KEY, components);
    }

存储内容包括:已提出的上次存储内容、SavedStateProvider提供的数据,并且以当前新数据为准

取出方法

    void performRestore(@NonNull Lifecycle lifecycle, @Nullable Bundle savedState) {
        if (mRestored) {
            throw new IllegalStateException("SavedStateRegistry was already restored.");
        }
        if (savedState != null) {
            mRestoredState = savedState.getBundle(SAVED_COMPONENTS_KEY);
        }

        lifecycle.addObserver(new GenericLifecycleObserver() {
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_START) {
                    mAllowingSavingState = true;
                } else if (event == Lifecycle.Event.ON_STOP) {
                    mAllowingSavingState = false;
                }
            }
        });

        mRestored = true;
    }

提取数据,并感知生命周期记录是否需要存储状态,最后设置提取状态为true

数据消耗

    public Bundle consumeRestoredStateForKey(@NonNull String key) {
        if (!mRestored) {
            throw new IllegalStateException("You can consumeRestoredStateForKey "
                    + "only after super.onCreate of corresponding component");
        }
        if (mRestoredState != null) {
            Bundle result = mRestoredState.getBundle(key);
            mRestoredState.remove(key);
            if (mRestoredState.isEmpty()) {
                mRestoredState = null;
            }
            return result;
        }
        return null;
    }

从已经解析的数据,并根据key值来取出

3.3 Recreator和其内部类

内部类SavedStateProvider完成AutoRecreated的存储,Recreator完成AutoRecreated的自动创建以及初始化

3.3.1 内部类SavedStateProvider

        SavedStateProvider(final SavedStateRegistry registry) {
            registry.registerSavedStateProvider(COMPONENT_KEY, this);
        }

        @NonNull
        @Override
        public Bundle saveState() {
            Bundle bundle = new Bundle();
            bundle.putStringArrayList(CLASSES_KEY, new ArrayList<>(mClasses));
            return bundle;
        }

        void add(String className) {
            mClasses.add(className);
        }

自动注册当前provider到SavedStateRegistry实例,其对应key值为androidx.savedstate.Restarter,对应存储数据为Bundle实例;Bundle内容为以classes_to_restore为key值,以AutoRecreated集合为value

3.3.2 Recreator类

在数据恢复时,其进行了生命周期注册,其生命监听处理:

    public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        if (event != Lifecycle.Event.ON_CREATE) {
            throw new AssertionError("Next event must be ON_CREATE");
        }
        source.getLifecycle().removeObserver(this);
        Bundle bundle = mOwner.getSavedStateRegistry()
                .consumeRestoredStateForKey(COMPONENT_KEY);
        if (bundle == null) {
            return;
        }
        ArrayList<String> classes = bundle.getStringArrayList(CLASSES_KEY);
        if (classes == null) {
            throw new IllegalStateException("Bundle with restored state for the component \""
                    + COMPONENT_KEY + "\" must contain list of strings by the key \""
                    + CLASSES_KEY + "\"");
        }
        for (String className : classes) {
            reflectiveNew(className);
        }
    }

生命周期调用后,则不再进行监听;根据androidx.savedstate.Restarter消耗提取出来的数据,并提取classes_to_restore中class数组,并且其必须是AutoRecreated的子类;然后调用reflectiveNew方法自动初始化;处理流程中可以看出其和内部类是存储和解析的两个过程;且存储的是AutoRecreated的子类的类数组

4 viewmodel、viewmodel-savestate库

viewmodel库定义了viewmodel的基础框架;viewmodel-savestate库利用savestate库中留下的AutoRecreated接口以及SavedStateProvider接口来完成,viewmodel的数据存储与恢复

4.1 viewmodel库

相关类图如下:不复杂,就不对代码进行解读了

viewmodel.png

  1. ViewModel:对自身tag进行管理;并存在onCleard回调清理所有tag事件
  2. AndroidViewModel:Application级别viewModel
  3. ViewModelProvider:提供viewmodel类
  4. ViewModelProvider.Factory以及子类: viewModel生产工厂
  5. ViewModelProvider.OnRequeryFactory:对viewmodel中数据进行存储
  6. HasDefaultViewModelProviderFactory:ViewModelProvider.Factory工厂提供类
  7. ViewModelStore:viewmodel实例存储销毁管理
  8. ViewModelStoreOwner:ViewModelStore提供者

也就是提供了viewmodel的生产、存储、获取;其本身并没有实现什么特殊功能;ViewModelProvider进行获取,ViewmodelStore进行缓存,ViewModelProvider.Factory以及子类进行生产;进而又抽象出ViewModelStoreOwner、HasDefaultViewModelProviderFactory,也即ViewModelOwner持有者、制造工厂的创造者;

在此库中,ViewModel类中并没有实现数据的恢复等功能,但在activity、fragment生命周期中配置变化销毁中,进行了ViewmodelStore的存储,进而使得ViewModel有了配置销毁时数据保存能力;

4.2 viewmodel-savestate库

类图如下:

viewmode-savestate.png

  1. ViewModelProvider.KeyedFactory实现类:viewModel工厂实现,并在onRequery方法中进行类中SavedStateHandle数据存储
  2. SavedStateHandle:ViewModel中数据存储与恢复类
  3. SavedStateHandleController:Viewmodel数据中控制类

其怎么保存与恢复数据呢,首先得从ViewModel工厂类来分析:AbstractSavedStateViewModelFactory抽象类在其它地方使用,就不分析了;而且数据必须可持久化(见SavedStateHandle.ACCEPTABLE_CLASSES中内容)

4.2.1 SavedStateViewModelFactory类

生产方法最终由下面方法产生

public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) {
        boolean isAndroidViewModel = AndroidViewModel.class.isAssignableFrom(modelClass);
        Constructor<T> constructor;
        if (isAndroidViewModel && mApplication != null) {
            constructor = findMatchingConstructor(modelClass, ANDROID_VIEWMODEL_SIGNATURE);
        } else {
            constructor = findMatchingConstructor(modelClass, VIEWMODEL_SIGNATURE);
        }
       
        if (constructor == null) {
            return mFactory.create(modelClass);
        }

        SavedStateHandleController controller = SavedStateHandleController.create(
                mSavedStateRegistry, mLifecycle, key, mDefaultArgs);
        try {
            T viewmodel;
            if (isAndroidViewModel && mApplication != null) {
                viewmodel = constructor.newInstance(mApplication, controller.getHandle());
            } else {
                viewmodel = constructor.newInstance(controller.getHandle());
            }
            viewmodel.setTagIfAbsent(TAG_SAVED_STATE_HANDLE_CONTROLLER, controller);
            return viewmodel;
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Failed to access " + modelClass, e);
        } catch (InstantiationException e) {
            throw new RuntimeException("A " + modelClass + " cannot be instantiated.", e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("An exception happened in constructor of "
                    + modelClass, e.getCause());
        }
    }
  1. 在找不到SavedStateHandle相关构造器时,使用内部工厂类进行生产(详情见构造器,这里不列出了)
  2. 生成SavedStateHandleController实例,生成viewmodel实例并设置tag为SavedStateHandleController实例

在SavedStateHandleController.create方法中进行了数据的恢复

4.2.2 SavedStateHandleController类

静态方法创建实例

   static SavedStateHandleController create(SavedStateRegistry registry, Lifecycle lifecycle,
            String key, Bundle defaultArgs) {
        Bundle restoredState = registry.consumeRestoredStateForKey(key);
        SavedStateHandle handle = SavedStateHandle.createHandle(restoredState, defaultArgs);
        SavedStateHandleController controller = new SavedStateHandleController(key, handle);
        controller.attachToLifecycle(registry, lifecycle);
        tryToAddRecreator(registry, lifecycle);
        return controller;
    }
  1. SavedStateRegistry中消耗数据;这里数据对应的key为viewmodel的class名字转化而来
  2. SavedStateHandle.createHandle创建SavedStateHandle对象,并依据参数恢复数据
  3. SavedStateHandleController实例创建,并进行生命周期监听,和数据提供者注册
  4. tryToAddRecreator:添加OnRecreation类到Recreator.SavedStateProvider中数据内,以便恢复数据时,自动执行;

attachToLifecycle方法

   void attachToLifecycle(SavedStateRegistry registry, Lifecycle lifecycle) {
        if (mIsAttached) {
            throw new IllegalStateException("Already attached to lifecycleOwner");
        }
        mIsAttached = true;
        lifecycle.addObserver(this);
        registry.registerSavedStateProvider(mKey, mHandle.savedStateProvider());
    }
  1. 生命周期监听,记录生命周期状态,并在销毁后取消
  2. 并注册其相关联的Viewmodel中数据SavedStateHandle对象的状态提供者;这样其数据在需要存储时自动存入进去

tryToAddRecreator静态方法

此方法,只是为把OnRecreation类到Recreator.SavedStateProvider中数据内,以便恢复数据时,自动执行;不过对状态有限制,也就是onPause和onResume之间的时机

    private static void tryToAddRecreator(SavedStateRegistry registry, Lifecycle lifecycle) {
        Lifecycle.State currentState = lifecycle.getCurrentState();
        if (currentState == INITIALIZED || currentState.isAtLeast(STARTED)) {
            registry.runOnNextRecreation(OnRecreation.class);
        } else {
            lifecycle.addObserver(new LifecycleEventObserver() {
                @Override
                public void onStateChanged(@NonNull LifecycleOwner source,
                        @NonNull Lifecycle.Event event) {
                    if (event == Lifecycle.Event.ON_START) {
                        lifecycle.removeObserver(this);
                        registry.runOnNextRecreation(OnRecreation.class);
                    }
                }
            });
        }
    }

4.2.3 OnRecreation类

仅仅只有一个方法

        @Override
        public void onRecreated(@NonNull SavedStateRegistryOwner owner) {
            if (!(owner instanceof ViewModelStoreOwner)) {
                throw new IllegalStateException(
                        "Internal error: OnRecreation should be registered only on components"
                                + "that implement ViewModelStoreOwner");
            }
            ViewModelStore viewModelStore = ((ViewModelStoreOwner) owner).getViewModelStore();
            SavedStateRegistry savedStateRegistry = owner.getSavedStateRegistry();
            for (String key : viewModelStore.keys()) {
                ViewModel viewModel = viewModelStore.get(key);
                attachHandleIfNeeded(viewModel, savedStateRegistry, owner.getLifecycle());
            }
            if (!viewModelStore.keys().isEmpty()) {
                savedStateRegistry.runOnNextRecreation(OnRecreation.class);
            }
        }

自动执行时,如果viewModelStore内容未销毁,则通过attachHandleIfNeeded方法进行Viewmodel的生命周期和数据处理;这样就会在不需要工厂创建时完成数据恢复

SavedStateHandleController类中的静态方法attachHandleIfNeeded

  static void attachHandleIfNeeded(ViewModel viewModel, SavedStateRegistry registry,
            Lifecycle lifecycle) {
        SavedStateHandleController controller = viewModel.getTag(
                TAG_SAVED_STATE_HANDLE_CONTROLLER);
        if (controller != null && !controller.isAttached()) {
            controller.attachToLifecycle(registry, lifecycle);
            tryToAddRecreator(registry, lifecycle);
        }
    }

通过tag获取SavedStateHandleController,并进行相应处理;详见上面对两个方法的分析

4.2.4 SavedStateHandle类

其中存储数据,还可以增加数据提供者,并且数据可以转换未liveData数据

存储过程

    private final SavedStateProvider mSavedStateProvider = new SavedStateProvider() {
        @SuppressWarnings("unchecked")
        @NonNull
        @Override
        public Bundle saveState() {
            // Get the saved state from each SavedStateProvider registered with this
            // SavedStateHandle, iterating through a copy to avoid re-entrance
            Map<String, SavedStateProvider> map = new HashMap<>(mSavedStateProviders);
            for (Map.Entry<String, SavedStateProvider> entry : map.entrySet()) {
                Bundle savedState = entry.getValue().saveState();
                set(entry.getKey(), savedState);
            }
            // Convert the Map of current values into a Bundle
            Set<String> keySet = mRegular.keySet();
            ArrayList keys = new ArrayList(keySet.size());
            ArrayList value = new ArrayList(keys.size());
            for (String key : keySet) {
                keys.add(key);
                value.add(mRegular.get(key));
            }

            Bundle res = new Bundle();
            // "parcelable" arraylists - lol
            res.putParcelableArrayList("keys", keys);
            res.putParcelableArrayList("values", value);
            return res;
        }
    };
  1. 内部数据提供者在SavedStateHandleController中进行了注册
  2. 其数据包括了mSavedStateProviders的数据、mRegular数据

恢复过程

static SavedStateHandle createHandle(@Nullable Bundle restoredState,
            @Nullable Bundle defaultState) {
        if (restoredState == null && defaultState == null) {
            return new SavedStateHandle();
        }

        Map<String, Object> state = new HashMap<>();
        if (defaultState != null) {
            for (String key : defaultState.keySet()) {
                state.put(key, defaultState.get(key));
            }
        }

        if (restoredState == null) {
            return new SavedStateHandle(state);
        }

        ArrayList keys = restoredState.getParcelableArrayList(KEYS);
        ArrayList values = restoredState.getParcelableArrayList(VALUES);
        if (keys == null || values == null || keys.size() != values.size()) {
            throw new IllegalStateException("Invalid bundle passed as restored state");
        }
        for (int i = 0; i < keys.size(); i++) {
            state.put((String) keys.get(i), values.get(i));
        }
        return new SavedStateHandle(state);
    }

在创建Viewmodel关联的SavedStateHandleController实例时创建,restoredState为已经解析的数据,defaultState为启动时附带数据;附带数据全部解析,restoredState取出相应key值;却没有取出所有相关mSavedStateProviders中数据,这需要这些实例主动去获取其值(暂时未见使用,可能是预留);这些数据全部存储在类变量mRegular中

LiveData实例获取

其本质上都是通过下面方法实现

    private <T> MutableLiveData<T> getLiveDataInternal(
            @NonNull String key,
            boolean hasInitialValue,
            @Nullable T initialValue) {
        MutableLiveData<T> liveData = (MutableLiveData<T>) mLiveDatas.get(key);
        if (liveData != null) {
            return liveData;
        }
        SavingStateLiveData<T> mutableLd;
        // double hashing but null is valid value
        if (mRegular.containsKey(key)) {
            mutableLd = new SavingStateLiveData<>(this, key, (T) mRegular.get(key));
        } else if (hasInitialValue) {
            mutableLd = new SavingStateLiveData<>(this, key, initialValue);
        } else {
            mutableLd = new SavingStateLiveData<>(this, key);
        }
        mLiveDatas.put(key, mutableLd);
        return mutableLd;
    }
  1. 是否已有缓存,mLiveDatas存着的即为缓存
  2. 生成LiveDatas实例,其类为SavingStateLiveData:同步变化mRegular中相应数据

为何要同步变化呢,因为livedata内数据,就是根据mRegular中变化,这样可以同步保存以便恢复时为正确内容

数据变化

   public <T> T get(@NonNull String key) {
        return (T) mRegular.get(key);
    }

    public <T> void set(@NonNull String key, @Nullable T value) {
        validateValue(value);
        @SuppressWarnings("unchecked")
        MutableLiveData<T> mutableLiveData = (MutableLiveData<T>) mLiveDatas.get(key);
        if (mutableLiveData != null) {
            mutableLiveData.setValue(value);
        } else {
            mRegular.put(key, value);
        }
    }

    public <T> T remove(@NonNull String key) {
        @SuppressWarnings("unchecked")
        T latestValue = (T) mRegular.remove(key);
        SavingStateLiveData<?> liveData = mLiveDatas.remove(key);
        if (liveData != null) {
            liveData.detach();
        }
        return latestValue;
    }

保持mRegular和mLiveDatas中数据同步变化;也是为了保存正确且必要的数据

SavingStateLiveData类

       public void setValue(T value) {
            if (mHandle != null) {
                mHandle.mRegular.put(mKey, value);
            }
            super.setValue(value);
        }

        void detach() {
            mHandle = null;
        }

其中数据变动保持与持有mHandle对象内保持一致;由于数据变动可以来在LiveData实例,所以在此能确保数据如何变化都会保持同步

5 小结

  1. LiveData如果不需要在配置变化或者异常销毁时恢复,则没有必要和ViewModel关联;
  2. ViewModel直接定义的变量可在配置变化时重新恢复;
  3. ViewModel可以增加子类,提供存在([Application,]SavedStateHandle)的构造器,在内部数据可以在异常情况下恢复,其数据必须满足相应要求;这种方式不适合在配置变化时使用,如需要按照2来做
  4. ViewModel使用ViewModelProvider实例来获取,ViewModelProvider参数来自持有者

技术变化都很快,但基础技术、理论知识永远都是那些;作者希望在余后的生活中,对常用技术点进行基础知识分享;如果你觉得文章写的不错,请给与关注和点赞;如果文章存在错误,也请多多指教!