ViewModel创建
1 | ViewModelProvider(this).get(CustomModel::class.java) |
- 点进源码查看ViewModelProvider实现
1 2 3 4 5 6 7 8 | // 实际上调用的方法是ViewModelProvider(activity.getViewModelStore, factory) public ViewModelProvider(@NonNull ViewModelStoreOwner owner) { // 对传入的参数进行处理 owner.getViewModelStore(), factory this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory ? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory() : NewInstanceFactory.getInstance()); } |
owner.getViewModelStore()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // ComponentActivity获取ViewModelStoreOwner(activity/fragment)的viewModelStore @NonNull @Override public ViewModelStore getViewModelStore() { if (getApplication() == null) { throw new IllegalStateException("Your activity is not yet attached to the " + "Application instance. You can't request ViewModel before onCreate call."); } if (mViewModelStore == null) { // 从NonConfigurationInstances.activity中获取ViewModel NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); if (nc != null) { // Restore the ViewModelStore from NonConfigurationInstances mViewModelStore = nc.viewModelStore; } if (mViewModelStore == null) { // 如果保存的状态为空且mViewModelStore为空,则直接创建ViewModelStore mViewModelStore = new ViewModelStore(); } } // mViewModelStore不为空直接返回 return mViewModelStore; } |
- 在上面方法中,我们注意到当ViewModelStore为null时,需要从NonConfigurationInstances中获取viewModelStore, 所以我们在点进去看一下NonConfigurationInstances到底做了什么
NonConfigurationInstances
- Activity状态保留我们一般都是通过onSaveInstanceState保存数据,还原时使用onRestoreInstanceState,但是这种方法保存数据具有一定的局限性:数据不可过大,数据需要序列化。Android还提供了另外一套保存和恢复机制,getLastNonConfigurationInstance和o’nRetainNonConfigurationInstance, 这两个方法可以通过一个包含状态的object对象来传递信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /** * ComponentActivity的NonConfigurationInstances */ static final class NonConfigurationInstances { Object custom; // 自定义内容 ViewModelStore viewModelStore; } /** * Activity中的NonConfigurationInstances */ static final class NonConfigurationInstances { Object activity; HashMap<String, Object> children; FragmentManagerNonConfig fragments; ArrayMap<String, LoaderManager> loaders; VoiceInteractor voiceInteractor; } /** * ComponentActivity onRetainNonConfigurationInstance重写Activity中的方法,当前ViewModelStoreOwner销毁保存信息 */ @Override @Nullable public final Object onRetainNonConfigurationInstance() { Object custom = onRetainCustomNonConfigurationInstance(); ViewModelStore viewModelStore = mViewModelStore; if (viewModelStore == null) { NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); if (nc != null) { // 保存Activity中的NonConfigurationInstances.activity的ViewModel viewModelStore = nc.viewModelStore; } } if (viewModelStore == null && custom == null) { return null; } NonConfigurationInstances nci = new NonConfigurationInstances(); nci.custom = custom; nci.viewModelStore = viewModelStore; return nci; } /** * 状态恢复, 返回Activity中的mLastNonConfigurationInstances.activity */ public Object getLastNonConfigurationInstance() { return mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.activity : null; } |
- 从上面代码可以看出,activity/fragment 销毁和重建保存和恢复的时ViewModelStore,那么ViewModel哪里去了?在ViewModelStore中通过HashMap存储者ViewModel
ViewModelStore(ViewModel存储容器)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // ViewModelStore public class ViewModelStore { // 通过HashMap存储ViewModel 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()); } // 在Activity和Fragment的onDestory方法中,会执行clear方法,执行所有ViewModel的onCleared的方法,清空Map集合里面的ViewModel public final void clear() { for (ViewModel vm : mMap.values()) { vm.clear(); } mMap.clear(); } } |
Factory
- ViewModelProvider的第二个参数是factory, Factory存在两个实现类:ViewModelProvider.AndroidViewModelFactory.getInstance(application);
或者 NewInstanceFactory.getInstance(),具体代码如下
NewInstanceFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public static class NewInstanceFactory implements Factory { private static NewInstanceFactory sInstance; /** * Retrieve a singleton instance of NewInstanceFactory. * * @return A valid {@link NewInstanceFactory} */ @NonNull static NewInstanceFactory getInstance() { if (sInstance == null) { sInstance = new NewInstanceFactory(); } return sInstance; } @SuppressWarnings("ClassNewInstance") @NonNull @Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { //noinspection TryWithIdenticalCatches try { // 返回ViewModel实例 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(NewInstanceFactory的直接子类)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory { private static AndroidViewModelFactory sInstance; /** * Retrieve a singleton instance of AndroidViewModelFactory. * * @param application an application to pass in {@link AndroidViewModel} * @return A valid {@link AndroidViewModelFactory} */ @NonNull public static AndroidViewModelFactory getInstance(@NonNull Application application) { if (sInstance == null) { sInstance = new AndroidViewModelFactory(application); } return sInstance; } private Application mApplication; /** * Creates a {@code AndroidViewModelFactory} * * @param application an application to pass in {@link AndroidViewModel} */ 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 { // 通过get方法传入的ViewModel返回带有applicationContext的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); } } |
通过get方法生成ViewModel实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | @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中HashMap的key return get(DEFAULT_KEY + ":" + canonicalName, modelClass); } @NonNull @MainThread public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) { // 通过Key产找到ViewModel ViewModel viewModel = mViewModelStore.get(key); // 如果获取的ViewModel和传入的ViewModel的Class的对象相同,则直接返回给ViewModel if (modelClass.isInstance(viewModel)) { if (mFactory instanceof OnRequeryFactory) { ((OnRequeryFactory) mFactory).onRequery(viewModel); } return (T) viewModel; } else { //noinspection StatementWithEmptyBody if (viewModel != null) { // TODO: log a warning. } } // 通过工厂生产一个ViewModel实例(可能带有applicationcontext) if (mFactory instanceof KeyedFactory) { viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass); } else { viewModel = (mFactory).create(modelClass); } mViewModelStore.put(key, viewModel); return (T) viewModel; } |
ViewModel源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | abstract class ViewModel // ViewModel通过HashMap存储CoroutineScope对象 private final Map<String, Object> mBagOfTags = new HashMap<>(); // ViewModel被销毁时内部执行clear()方法, @MainThread final void clear() { mCleared = true; if (mBagOfTags != null) { synchronized (mBagOfTags) { for (Object value : mBagOfTags.values()) { // 取消viewModelScope作用域的协程 closeWithRuntimeException(value); } } } onCleared(); } // 取消CoroutineScope private static void closeWithRuntimeException(Object obj) { if (obj instanceof Closeable) { try { ((Closeable) obj).close(); } catch (IOException e) { throw new RuntimeException(e); } } } // 如果JOB_KEY已存在且对应的协程作用域不为空则返回对象,否则创建新的协程作用域,并设置JOB_KEY @SuppressWarnings("unchecked") <T> T setTagIfAbsent(String key, T newValue) { T previous; synchronized (mBagOfTags) { previous = (T) mBagOfTags.get(key); if (previous == null) { mBagOfTags.put(key, newValue); } } T result = previous == null ? newValue : previous; if (mCleared) { closeWithRuntimeException(result); } return result; } // 通过JOB_KEY从HashMap中返回相应的协程作用域 @SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"}) <T> T getTag(String key) { synchronized (mBagOfTags) { return (T) mBagOfTags.get(key); } } } |
AndroidViewModel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class AndroidViewModel extends ViewModel { @SuppressLint("StaticFieldLeak") private Application mApplication; public AndroidViewModel(@NonNull Application application) { mApplication = application; } // 返回application @SuppressWarnings({"TypeParameterUnusedInFormals", "unchecked"}) @NonNull public <T extends Application> T getApplication() { return (T) mApplication; } } |