ViewModel源码解析

作者: 几行代码 | 来源:发表于2020-02-29 10:19 被阅读0次

    ViewModel具体怎么使用前面我们已经演示过了,这是链接:https://www.jianshu.com/p/5a7f36c7dd9e
    下面分析一下,基于SDK 28:
    第一步:根据 Activity 或者 Fragment 获得 ViewModelProvider

    ViewModelProvider viewModelProvider = ViewModelProviders.of(MainActivity.this);
    

    看看这个源码中是怎么实现的

     /**
         * 使用 ViewModelProvider.AndroidViewModelFactory 来实例化新的 ViewModels.
         */
        @NonNull
        @MainThread
        public static ViewModelProvider of(@NonNull FragmentActivity activity) {
            return of(activity, null);
        }
    
    /**
         * 通过给定的工厂来实例化一个新的 ViewModels.
         */
        @NonNull
        @MainThread
        public static ViewModelProvider of(@NonNull FragmentActivity activity, @Nullable Factory factory) {
            Application application = checkApplication(activity);
            if (factory == null) {
                // 获取默认的单例 AndroidViewModelFactory,它内部是通过反射来创建具体的 ViewModel
                factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
            }
            return new ViewModelProvider(activity.getViewModelStore(), factory);
        }
    
    /**
         * 通过Activity获取可用的Application或者检测Activity是否可用
         */
        private static Application checkApplication(Activity activity) {
            Application application = activity.getApplication();
            if (application == null) {
                throw new IllegalStateException("Your activity/fragment is not yet attached to "
                        + "Application. You can't request ViewModel before onCreate call.");
            }
            return application;
        }
    
        /**
         * 通过Fragment获取Activity或者检测Fragment是否可用
         */
        private static Activity checkActivity(Fragment fragment) {
            Activity activity = fragment.getActivity();
            if (activity == null) {
                throw new IllegalStateException("Can't create ViewModelProvider for detached fragment");
            }
            return activity;
        }
    
    在类 ViewModelProvider 有下面的方法
     /**
         * AndroidViewModelFactory 在正常情况下是全局单例只有一个,只是一个反射创建对象的工具类
         */
        public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {
    
            private static AndroidViewModelFactory sInstance;
    
            // 获得 AndroidViewModelFactory 单例
            @NonNull
            public static AndroidViewModelFactory getInstance(@NonNull Application application) {
                if (sInstance == null) {
                    sInstance = new AndroidViewModelFactory(application);
                }
                return sInstance;
            }
    
            private Application mApplication;
    
            // 构造方式是 public 的,是可以 new 一个 AndroidViewModelFactory 出来的
            public AndroidViewModelFactory(@NonNull Application application) {
                mApplication = application;
            }
    
            @NonNull
            @Override
            public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
                if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
                    //noinspection TryWithIdenticalCatches
                    try {
                        // 创建ViewModel的关键地方,根据给出的Class反射创建需要的ViewModel
                        return modelClass.getConstructor(Application.class).newInstance(mApplication);
                    } catch (NoSuchMethodException e) {
                        throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                    } catch (InstantiationException e) {
                        throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                    } catch (InvocationTargetException e) {
                        throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                    }
                }
                return super.create(modelClass);
            }
        }
    
    下面的方法在ComponentActivity
    // TODO 返回与此 activity 关联的 ViewModelStore
        @NonNull
        public ViewModelStore getViewModelStore() {
            if (this.getApplication() == null) {
                throw new IllegalStateException("Your activity is not yet attached to the Application instance. You can't request ViewModel before onCreate call.");
            } else {
                if (this.mViewModelStore == null) {
                    ComponentActivity.NonConfigurationInstances nc = (ComponentActivity.NonConfigurationInstances)this.getLastNonConfigurationInstance();
                    if (nc != null) {
                        // TODO 从非配置实例还原 ViewModelStore ,从这里可以实现 ViewModel 跨越 Activity/Fragment的 生命周期
                        this.mViewModelStore = nc.viewModelStore;
                    }
                    // 为空就新创建一个
                    if (this.mViewModelStore == null) {
                        this.mViewModelStore = new ViewModelStore();
                    }
                }
    
                return this.mViewModelStore;
            }
        }
    

    获取对应的 ViewModelStore

    // TODO 返回与此 activity 关联的 ViewModelStore
        @NonNull
        public ViewModelStore getViewModelStore() {
            if (this.getApplication() == null) {
                throw new IllegalStateException("Your activity is not yet attached to the Application instance. You can't request ViewModel before onCreate call.");
            } else {
                if (this.mViewModelStore == null) {
                    ComponentActivity.NonConfigurationInstances nc = (ComponentActivity.NonConfigurationInstances)this.getLastNonConfigurationInstance();
                    if (nc != null) {
                        // TODO 从非配置实例还原 ViewModelStore ,从这里可以实现 ViewModel 跨越 Activity/Fragment的 生命周期
                        this.mViewModelStore = nc.viewModelStore;
                    }
                    // 为空就新创建一个
                    if (this.mViewModelStore == null) {
                        this.mViewModelStore = new ViewModelStore();
                    }
                }
    
                return this.mViewModelStore;
            }
        }
    

    PS:
    1.从上面可以知道根据传入的 Activity 或者 fragment 获取到 Application 从而得到 AndroidViewModelFactory
    2.在 Activity 的父类 ComponentActivity 中会有方法getViewModelStore() 获取 ViewModelStore
    3.通过 AndroidViewModelFactory、ViewModelStore,创建出 ViewModelProvider 对象

    第二步:使用 ViewModelProvider 反射创建需要的 ViewModel

    MainViewModel mainViewModel = viewModelProvider.get(MainViewModel.class);
    

    跟进源码中看是怎么实现 get 方法的
    ViewModelProvider类中

    /**
         * 创建一个ViewModelProvider,使用 ViewModelProvider 内部的全局单例 AndroidViewModelFactory 来反射创建 ViewModel,并把创建的ViewModel存入传入的ViewModelStore中!
         * @param modelClass ViewModel 的子类的 class
         */
        @NonNull
        @MainThread
        public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
            String canonicalName = modelClass.getCanonicalName();
            if (canonicalName == null) {
                throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
            }
            // ViewModelStore 存储 ViewModel key 的获取:  DEFAULT_KEY 和 类名组成一个key值
            return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
        }
    
        @NonNull
        @MainThread
        public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
            ViewModel viewModel = mViewModelStore.get(key); // 先从缓存中获取
    
            if (modelClass.isInstance(viewModel)) {  // 缓存有就直接返回,否则就用 Factory 从新创建
                //noinspection unchecked
                return (T) viewModel;
            } else {
                //noinspection StatementWithEmptyBody
                if (viewModel != null) {
                    // TODO: log a warning.
                }
            }
            if (mFactory instanceof KeyedFactory) {
                viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
            } else {
                viewModel = (mFactory).create(modelClass); // 创建对应的 viewModel
            }
            mViewModelStore.put(key, viewModel);  // 把创建好的 viewModel 存储到 ViewModelStore 的 HashMap 的 put 方法中
            //noinspection unchecked
            return (T) viewModel;
        }
    

    总结:
    从上面可以看出,会先根据 类的全名+默认值作为key,从Map 中获取缓存,如果没有缓存在根据第一步中获取到的 Factory 创建一个新的 viewModel

    未命名文件.jpg

    源码目录:


    源码目录

    可以看到源码相对来说很少
    我贴出来,在源码中我都加了注释,就不详细讲解了

    AndroidViewModel

    package androidx.lifecycle;
    
    import android.annotation.SuppressLint;
    import android.app.Application;
    
    import androidx.annotation.NonNull;
    
    /**
     * 感知应用程序的上下文
     * <p>
     * 子类必须有一个接受 application 作为唯一参数的构造函数。
     * <p>
     */
    public class AndroidViewModel extends ViewModel {
        @SuppressLint("StaticFieldLeak")
        private Application mApplication;
    
        public AndroidViewModel(@NonNull Application application) {
            mApplication = application;
        }
    
        /**
         * 返回对应的 Application
         */
        @SuppressWarnings("TypeParameterUnusedInFormals")
        @NonNull
        public <T extends Application> T getApplication() {
            //noinspection unchecked
            return (T) mApplication;
        }
    }
    

    ViewModel

    package androidx.lifecycle;
    
    import androidx.annotation.MainThread;
    import androidx.annotation.Nullable;
    
    import java.io.Closeable;
    import java.io.IOException;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     viewModel是一个类,负责为 activity 活动或 fragment 准备和管理数据。
     它还处理 activity / fragment 与 application  其余部分的通信(例如,调用业务逻辑类)。
     <P>
     ViewModel 总是与作用域(activity 或 fragment)关联创建的,并且只要作用域是活动的,它就将被保留。例如,如果它是一个 activity,直到完成为止。
     <P>
     换句话说,这意味着,如果由于配置更改(例如旋转)而销毁了 ViewModel 的所有者,则该 ViewModel 将不会被销毁。所有者的新实例将重新连接到现有的 ViewModel。
     <P>
     ViewModel 的目的是获取和保存 Activity 或 Fragment 所需的信息。Activity 或 Fragment 应该能够观察到 ViewModel 中的更改。
     ViewModels 通常通过 LiveData 或 Android 数据绑定公开此信息。您还可以使用您喜欢的框架中的任何可观察性构造。
     <P>
     ViewModel 的唯一职责是管理UI的数据。它不应访问视图层次结构或保留对 Activity 或 Fragment 的引用。
     <P>
     从 Activity 的角度来看,典型的用法是:
     < PRE>
    
     * public class UserActivity extends Activity {
     *
     *     {@literal @}Override
     *     protected void onCreate(Bundle savedInstanceState) {
     *         super.onCreate(savedInstanceState);
     *         setContentView(R.layout.user_activity_layout);
     *
     *         final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class);
     *
     *         viewModel.getUser().observe(this, new Observer<User>() {
     *            {@literal @}Override
     *             public void onChanged(@Nullable User data) {
     *                 // update ui.
     *             }
     *         });
     *
     *         findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
     *             {@literal @}Override
     *             public void onClick(View v) {
     *                  viewModel.doAction();
     *             }
     *         });
     *     }
     * }
     * </pre>
     *
     * ViewModel 将是:
     * <pre>
     * public class UserModel extends ViewModel {
     *     private final MutableLiveData<User> userLiveData = new MutableLiveData();
     *
     *     public LiveData<User> getUser() {
     *         return userLiveData;
     *     }
     *
     *     public UserModel() {
     *         // trigger user load. 触发用户加载
     *     }
     *
     *     void doAction() {
     *         // depending on the action, do necessary business logic calls and update the userLiveData.
     *         // 根据操作,进行必要的业务逻辑调用并更新 userLiveData。
     *     }
     * }
     * </pre>
     *
     * <p>
     *  ViewModels 还可以用作 Activity 及不同 Fragment 之间的通信层。
     *  每个 Fragment 可以通过其 Activity 使用相同的 key 来获取 ViewModel。
     *  这允许 Fragment 之间以一种非耦合的方式进行通信,这样它们就不需要直接与另一个 Fragment 通信。
     * <pre>
     * public class MyFragment extends Fragment {
     *     public void onStart() {
     *         UserModel userModel = ViewModelProviders.of(getActivity()).get(UserModel.class);
     *     }
     * }
     * </pre>
     * </>
     */
    public abstract class ViewModel {
        @Nullable
        private final ConcurrentHashMap<String, Object> mBagOfTags = new ConcurrentHashMap<>();
        private volatile boolean mCleared = false;
    
        /**
         * This method will be called when this ViewModel is no longer used and will be destroyed.
         * 当不再使用此 ViewModel 时,将调用此方法并将其销毁。
         * <p>
         * It is useful when ViewModel observes some data and you need to clear this subscription to
         * prevent a leak of this ViewModel.
         * 当 ViewModel 观察到一些数据,并且您需要清除此订阅以防止此 ViewModel 泄漏时,它非常有用。
         */
        @SuppressWarnings("WeakerAccess")
        protected void onCleared() {
        }
    
        @MainThread
        final void clear() {
            mCleared = true;
            // Since clear() is final, this method is still called on mock objects
            // and in those cases, mBagOfTags is null. It'll always be empty though
            // because setTagIfAbsent and getTag are not final so we can skip
            // clearing it
            // 由于clear()是final,所以仍然对模拟对象调用此方法,在这些情况下,mBagOfTags 为空。
            // 但它总是空的,因为 setTagIfAbsent 和 getTag 不是最终版本,所以我们可以跳过清除它。
            if (mBagOfTags != null) {
                for (Object value : mBagOfTags.values()) {
                    // see comment for the similar call in setTagIfAbsent 请参阅 setTagIfAbsent 中类似调用的注释
                    closeWithRuntimeException(value);
                }
            }
            onCleared();
        }
    
        /**
         * 设置与此ViewModel关联的标记和键。
         * 如果给定的 newValue 是 Closeable,它将关闭一次 clear()。
         * < P>
         * 如果已经为给定的键设置了值,则此调用不执行任何操作,并且返回当前关联的值,给定的 newValue 将被忽略
         * < P>
         * 如果 viewModel 已经清除,那么如果返回的对象实现了 Closeable,则会对该对象调用 close()。同一对象可能会收到多个关闭调用,因此方法应该是等幂的。
         */
        <T> T setTagIfAbsent(String key, T newValue) {
            assert mBagOfTags != null;
            @SuppressWarnings("unchecked")
            T previous = (T) mBagOfTags.putIfAbsent(key, newValue);
            T result = previous == null ? newValue : previous;
            if (mCleared) {
                // It is possible that we'll call close() multiple times on the same object, but
                // Closeable interface requires close method to be idempotent:
                // "if the stream is already closed then invoking this method has no effect." (c)
                // 我们可能会在同一个对象上多次调用close(),但 Closeable 接口要求 close 方法为等幂:“如果流已经关闭,则调用此方法无效。”
                closeWithRuntimeException(result);
            }
            return result;
        }
    
        /**
         * Returns the tag associated with this viewmodel and the specified key.
         * 返回与此ViewModel和指定键关联的标记。
         */
        @SuppressWarnings("TypeParameterUnusedInFormals")
        <T> T getTag(String key) {
            //noinspection unchecked
            return (T) mBagOfTags.get(key);
        }
    
        // 我们可能会在同一个对象上多次调用close(),但 Closeable 接口要求 close 方法为等幂:“如果流已经关闭,则调用此方法无效。”
        private static void closeWithRuntimeException(Object obj) {
            if (obj instanceof Closeable) {
                try {
                    ((Closeable) obj).close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    

    ViewModelProvider

    package androidx.lifecycle;
    
    import android.app.Application;
    
    import androidx.annotation.MainThread;
    import androidx.annotation.NonNull;
    
    import java.lang.reflect.InvocationTargetException;
    
    /**
     * ViewModelProvider 是每次获取创建 ViewModel 的时候都会创建一个新的
     */
    @SuppressWarnings("WeakerAccess")
    public class ViewModelProvider {
    
        private static final String DEFAULT_KEY = "androidx.lifecycle.ViewModelProvider.DefaultKey";
    
        /**
         * Factory 接口的实现负责实例化 ViewModels。
         */
        public interface Factory {
            /**
             * 创建给定 @code Class 类的新实例
             *
             * @param modelClass 新实例的 class
             * @param <T>        ViewModel 类型的泛型参数.
             * @return 返回新创建的 ViewModel
             */
            @NonNull
            <T extends ViewModel> T create(@NonNull Class<T> modelClass);
        }
    
        /**
         * factory 接口的实现负责实例化 ViewModels。
         * 这是 factory 的更高级版本,它接收为请求指定的密钥
         */
        abstract static class KeyedFactory implements Factory {
            /**
             * @param key a key  在 ViewModelStore 存储的 ViewModel 的 key
             * @return 实例化对应的 ViewModel
             */
            @NonNull
            public abstract <T extends ViewModel> T create(@NonNull String key,
                                                           @NonNull Class<T> modelClass);
    
            @NonNull
            @Override
            public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
                throw new UnsupportedOperationException("create(String, Class<?>) must be called on "
                        + "implementaions of KeyedFactory");
            }
        }
    
        private final Factory mFactory;
        private final ViewModelStore mViewModelStore;
    
        /**
         * @param owner   ViewModelStore 用于保存 ViewModels
         * @param factory Factory 用于创建新的 ViewModels
         */
        public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {
            this(owner.getViewModelStore(), factory);
        }
    
        public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
            mFactory = factory;
            mViewModelStore = store;
        }
    
        /**
         * 创建一个ViewModelProvider,使用 ViewModelProvider 内部的全局单例 AndroidViewModelFactory 来反射创建 ViewModel,并把创建的ViewModel存入传入的ViewModelStore中!
         * @param modelClass ViewModel 的子类的 class
         */
        @NonNull
        @MainThread
        public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
            String canonicalName = modelClass.getCanonicalName();
            if (canonicalName == null) {
                throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
            }
            // ViewModelStore 存储 ViewModel key 的获取:  DEFAULT_KEY 和 类名组成一个key值
            return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
        }
    
        @NonNull
        @MainThread
        public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
            ViewModel viewModel = mViewModelStore.get(key); // 先从缓存中获取
    
            if (modelClass.isInstance(viewModel)) {  // 缓存有就直接返回,否则就用 Factory 从新创建
                //noinspection unchecked
                return (T) viewModel;
            } else {
                //noinspection StatementWithEmptyBody
                if (viewModel != null) {
                    // TODO: log a warning.
                }
            }
            if (mFactory instanceof KeyedFactory) {
                viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
            } else {
                viewModel = (mFactory).create(modelClass); // 创建对应的 viewModel
            }
            mViewModelStore.put(key, viewModel);  // 把创建好的 viewModel 存储到 ViewModelStore 的 HashMap 的 put 方法中
            //noinspection unchecked
            return (T) viewModel;
        }
    
        /**
         * Simple factory, which calls empty constructor on the give class.  简单工厂,它在给定类上调用空构造函数
         */
        public static class NewInstanceFactory implements Factory {
    
            @SuppressWarnings("ClassNewInstance")
            @NonNull
            @Override
            public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
                //noinspection TryWithIdenticalCatches
                try {
                    return modelClass.newInstance();
                } catch (InstantiationException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                }
            }
        }
    
        /**
         * AndroidViewModelFactory 在正常情况下是全局单例只有一个,只是一个反射创建对象的工具类
         */
        public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {
    
            private static AndroidViewModelFactory sInstance;
    
            // 获得 AndroidViewModelFactory 单例
            @NonNull
            public static AndroidViewModelFactory getInstance(@NonNull Application application) {
                if (sInstance == null) {
                    sInstance = new AndroidViewModelFactory(application);
                }
                return sInstance;
            }
    
            private Application mApplication;
    
            // 构造方式是 public 的,是可以 new 一个 AndroidViewModelFactory 出来的
            public AndroidViewModelFactory(@NonNull Application application) {
                mApplication = application;
            }
    
            @NonNull
            @Override
            public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
                if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
                    //noinspection TryWithIdenticalCatches
                    try {
                        // 创建ViewModel的关键地方,根据给出的Class反射创建需要的ViewModel
                        return modelClass.getConstructor(Application.class).newInstance(mApplication);
                    } catch (NoSuchMethodException e) {
                        throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                    } catch (InstantiationException e) {
                        throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                    } catch (InvocationTargetException e) {
                        throw new RuntimeException("Cannot create an instance of " + modelClass, e);
                    }
                }
                return super.create(modelClass);
            }
        }
    }
    

    ViewModelProviders

    package androidx.lifecycle;
    
    import android.app.Activity;
    import android.app.Application;
    
    import androidx.annotation.MainThread;
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.fragment.app.FragmentActivity;
    import androidx.lifecycle.ViewModelProvider.Factory;
    
    /**
     * ViewModel 的创建不可直接 new,需要使用这个 ViewModelProviders 才能与 Activity 或者 Fragment 的生命周期关联起来!
     * ViewModel 的存在是依赖 Activity 或者 Fragment的,不管你在什么地方获取 ViewModel,
     * 只要你用的是相同的 Activity 或者 Fragment,那么获取到的 ViewModel 将是同一个 (前提是key值是一样的),所以 ViewModel 也具有数据共享的作用!
     */
    public class ViewModelProviders {
    
        /**
         * @deprecated This class should not be directly instantiated  不应直接实例化此类
         */
        @Deprecated
        public ViewModelProviders() {
        }
    
        /**
         * 通过Activity获取可用的Application或者检测Activity是否可用
         */
        private static Application checkApplication(Activity activity) {
            Application application = activity.getApplication();
            if (application == null) {
                throw new IllegalStateException("Your activity/fragment is not yet attached to "
                        + "Application. You can't request ViewModel before onCreate call.");
            }
            return application;
        }
    
        /**
         * 通过Fragment获取Activity或者检测Fragment是否可用
         */
        private static Activity checkActivity(Fragment fragment) {
            Activity activity = fragment.getActivity();
            if (activity == null) {
                throw new IllegalStateException("Can't create ViewModelProvider for detached fragment");
            }
            return activity;
        }
    
        /**
         * 通过Fragment获得ViewModelProvider
         * ViewModelProvider.AndroidViewModelFactory 来实例化新的 ViewModels
         */
        @NonNull
        @MainThread
        public static ViewModelProvider of(@NonNull Fragment fragment) {
            return of(fragment, null);
        }
    
        /**
         * 使用 ViewModelProvider.AndroidViewModelFactory 来实例化新的 ViewModels.
         */
        @NonNull
        @MainThread
        public static ViewModelProvider of(@NonNull FragmentActivity activity) {
            return of(activity, null);
        }
    
        /**
         * 通过给定的工厂来实例化一个新的 ViewModels.
         */
        @NonNull
        @MainThread
        public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) {
            Application application = checkApplication(checkActivity(fragment));
            if (factory == null) {
                // 获取默认的单例 AndroidViewModelFactory,它内部是通过反射来创建具体的 ViewModel
                factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
            }
            return new ViewModelProvider(fragment.getViewModelStore(), factory);
        }
    
        /**
         * 通过给定的工厂来实例化一个新的 ViewModels.
         */
        @NonNull
        @MainThread
        public static ViewModelProvider of(@NonNull FragmentActivity activity, @Nullable Factory factory) {
            Application application = checkApplication(activity);
            if (factory == null) {
                // 获取默认的单例 AndroidViewModelFactory,它内部是通过反射来创建具体的 ViewModel
                factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
            }
            return new ViewModelProvider(activity.getViewModelStore(), factory);
        }
    
        /**
         * 工厂可创建 AndroidViewModel 和 ViewModel,具有空构造函数的.
         * <p>
         * 不推荐使用 ViewModelProvider.AndroidViewModelFactory
         */
        @SuppressWarnings("WeakerAccess")
        @Deprecated
        public static class DefaultFactory extends ViewModelProvider.AndroidViewModelFactory {
            /**
             * 不推荐使用 ViewModelProvider.AndroidViewModelFactory 和
             * ViewModelProvider.AndroidViewModelFactory.getInstance(Application)的方式创建 AndroidViewModelFactory
             */
            @Deprecated
            public DefaultFactory(@NonNull Application application) {
                super(application);
            }
        }
    }
    

    ViewModelStore

    package androidx.lifecycle;
    
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * 用来存储 ViewModel
     * <p>
     * 必须通过配置更改保留 ViewModelStore 的实例:
     * <p>
     * 如果此 ViewModelStore 的所有者由于配置而被销毁并重新创建
     * 更改,所有者的新实例仍应具有相同的旧实例
     * <p>
     * 如果此 ViewModelStore 的所有者被销毁,并且不会被重新创建,
     * 然后它应该在这个 viewModelStore 上调用 clear(),因此 ViewModels 通知他们不再使用。
     * 当Activity或者Fragment销毁的时候就会调用clear方法
     *
     * TODO ViewModelStore 是每一个 Activity 或者 Fragment 都有一个
     */
    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());
        }
    
        /**
         * 清除内部存储并通知 ViewModel 它们不再使用
         */
        public final void clear() {
            for (ViewModel vm : mMap.values()) {
                vm.clear();
            }
            mMap.clear();
        }
    }
    

    ViewModelStoreOwner

    package androidx.lifecycle;
    
    import androidx.annotation.NonNull;
    
    /**
     * 此接口实现的职责是在配置更改期间保留所拥有的 ViewModelStore,并在要销毁此范围时调用 viewModelStore clear()。
     * SDK27+版本,都是V4包下的 FragmentActivity 和 Fragment 实现了这二个接口
     */
    @SuppressWarnings("WeakerAccess")
    public interface ViewModelStoreOwner {
    
        @NonNull
        ViewModelStore getViewModelStore();
    }
    

    ViewModelStores

    package androidx.lifecycle;
    
    import androidx.annotation.MainThread;
    import androidx.annotation.NonNull;
    import androidx.fragment.app.Fragment;
    import androidx.fragment.app.FragmentActivity;
    
    /**
     * Factory methods for {@link ViewModelStore} class.
     */
    @SuppressWarnings("WeakerAccess")
    public class ViewModelStores {
    
        private ViewModelStores() {
        }
    
        /**
         * 如果你的 Activity 实现了 ViewModelStoreOwner 接口具备了提供 ViewModelStore 的功能就直接获取返回
         * TODO 为 Activity 创建 ViewModelStore
         */
        @Deprecated
        @NonNull
        @MainThread
        public static ViewModelStore of(@NonNull FragmentActivity activity) {
            return activity.getViewModelStore();
        }
    
        /**
         * 如果你的 Fragment 实现了 ViewModelStoreOwner 接口具备了提供 ViewModelStore 的功能就直接获取返回
         * TODO 为 Fragment 创建 ViewModelStore
         */
        @Deprecated
        @NonNull
        @MainThread
        public static ViewModelStore of(@NonNull Fragment fragment) {
            return fragment.getViewModelStore();
        }
    }
    

    这里特意说明一下 ViewModelStore ,通过源码大家可以知道 这个是存储和清除 ViewModel 的,存储的操作是在
    ViewModelProvider.get(),方法中执行的,每新创建一个 ViewModel 就添加进去


    image.png

    清除是在 Activity 中执行的,代码如下:


    image.png

    相关文章

      网友评论

        本文标题:ViewModel源码解析

        本文链接:https://www.haomeiwen.com/subject/adeofctx.html