概览 ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。 ViewModel 对象存在的时间范围是获取 ViewModel 时传递给 ViewModelProvider 的 Lifecycle。ViewModel 将一直留在内存中,直到限定其存在时间范围的 Lifecycle 永久消失:对于 activity,是在 activity 完成时;而对于 fragment,是在 fragment 分离时。
 
如下图生命周期: 在系统首次调用 Activity 对象的 onCreate() 方法时请求 ViewModel。系统可能会在 activity 的整个生命周期内多次调用 onCreate(),如在旋转设备屏幕时。ViewModel 存在的时间范围是从您首次请求 ViewModel 直到 activity 完成并销毁。
特点 
1.横竖屏切换,包括Activity重建,数据可依然保存。 
2.同一个Activity下,Fragment之间的数据共享。同理在不同Activity中也可以共享ViewModel数据 
 
源码分析 我们在使用时是这样创建viewmodel的:
1 ViewModelProviders.of(this).get(MyViewModel::class.java) 
 
从上看出,Factory不传,默认为null
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public static ViewModelProvider of(@NonNull FragmentActivity activity,         @Nullable Factory factory) {     Application application = checkApplication(activity);     if (factory == null) {         factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);     }     return new ViewModelProvider(activity.getViewModelStore(), factory); } // getViewModelStore是在父类FragmentActivity中的; 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) {             mViewModelStore = new ViewModelStore();         }         return mViewModelStore;     } 
 
但是在2.2.0 中 ViewModelProviders被弃用。需要用新的方式获取:
1 ViewModelProvider(this,ViewModelProvider.NewInstaanceFactory()).get(MyViewModel::class.java) 
 
接着看ViewModelStoreOwner,就是this,说明它是一个接口,并且,我们的Activity一定是实现了这个接口。
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 public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) {     this(owner.getViewModelStore(), factory); } // 就是拿到ViewModelStore,如果是高版本,这里应该还有个nc判断,android-28版本nc在onCreate里 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.");     }     // nc保存了viewModelStore,所以横竖屏切换,数据不会丢失。     if(mViewModelStore == null){         NonConfigurationInstances nc =                     (NonConfigurationInstances) getLastNonConfigurationInstance();         if (nc != null) {             mViewModelStore = nc.viewModelStore;         }      }     if (mViewModelStore == null) {         mViewModelStore = new ViewModelStore();     }     return mViewModelStore; } //mViewModelStore专门存储ViewModel public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {     mFactory = factory;     this.mViewModelStore = store; } 
 
看以下继承关系:
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 public class FragmentActivity extends ComponentActivity implements         ViewModelStoreOwner,         ActivityCompat.OnRequestPermissionsResultCallback,         ActivityCompat.RequestPermissionsRequestCodeValidator { }    // 这个接口只有一个ViewModelStore public interface ViewModelStoreOwner {     @NonNull     ViewModelStore getViewModelStore(); } // ViewModelStore是啥?就是存储了一个map,map里存的是viewmodel,同时提供了一个clear方法,用于清理map缓存。 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);     }     /**      *  Clears internal storage and notifies ViewModels that they are no longer used.      */     public final void clear() {         for (ViewModel vm : mMap.values()) {             vm.onCleared();         }         mMap.clear();     } } 
 
接着看get方法
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 private static final String DEFAULT_KEY = "androidx.lifecycle.ViewModelProvider.DefaultKey";  @MainThread public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {     String canonicalName = modelClass.getCanonicalName();     return get(DEFAULT_KEY + ":" + canonicalName, modelClass); }  @MainThread public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {     ViewModel viewModel = mViewModelStore.get(key);     if (modelClass.isInstance(viewModel)) {//缓存里是否有,有就直接返回。         //noinspection unchecked         return (T) viewModel;     } else {         //noinspection StatementWithEmptyBody         if (viewModel != null) {             // TODO: log a warning.         }     }     viewModel = mFactory.create(modelClass);//通过mFactory创建ViewModel     mViewModelStore.put(key, viewModel);//存储到mViewModelStore     //noinspection unchecked     return (T) viewModel;//并返回ViewModel } 
 
那Factory如何根据class创建ViewMoel的?通过反射,拿到我们自定义的MyViewModel
1 2 3 4 5 6 7  public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {     //noinspection TryWithIdenticalCatches     try {         return modelClass.newInstance();     } catch (Exception e) {     }  } 
 
所以,ViewModelProvider(this,ViewModelProvider.NewInstaanceFactory()).get(MyViewModel::class.java) 这段代码一执行。就会通过工厂NewInstaanceFactory,反射实例化MyViewModel存储到了ViewModelStore中。 那viewmodel是啥时候销毁的?是在onDestroy生命周期中,所以,这里不需要我们手动去做,框架帮我们做了。同理,无论activity如何操作,旋转,重建,viewmode都不会销毁,数据都会保存,只有最后销毁,才清除掉。同时跟lifecycle解绑。
1 2 3 4 5 6 7 protected void onDestroy() {        super.onDestroy();        if (mViewModelStore != null && !isChangingConfigurations()) {            mViewModelStore.clear();        }        mFragments.dispatchDestroy();    } 
 
参考资料 developer.android.google.cn 
        
            
        
        
          
              Ursprünglicher Link: http://nunu03.github.io/2022/06/02/ViewModel源码解析/ 
              Copyright-Erklärung: 转载请注明出处.