以生命周期的方式存储和管理界面相关的数据,从界面控制器逻辑中分离出视图数据所有权,让代码更易行且更高效
注:
ViewModelProvider(ViewModelStoreOwner owner, Factory factory),使用这个构造参数创建了ViewModelProvider,再通过ViewModelProvider的get方法获取想要的viewModel,所以传入的this(即Activity或者Application)需要继承自ViewModelStoreOwner,如果你的Activity继承自AppCompatActivity或者FragmentActivity就不需要管,因为它们默认已经实现了ViewModelStoreOwner接口
传入的第一个参数ViewModelStoreOwner即将当前界面控制器与ViewModelProvider进行了绑定,ViewModelProvider内部有一个属性ViewModelStore就是通过ViewModelStoreOwner.getViewModelStore()获取的,ViewModelStore里维护一个HashMap,即存储当前界面控制器需要观察的所有ViewModel,在界面控制器销毁时调用ViewModelStore的clear方法,在这里对map里面所有的ViewModel执行onCleared,然后清空map
当配置发生变化时虽然Activity调用了onDestroy方法但是ViewModel还是之前的ViewModel,而真正销毁时调用的onDestroy就会调用ViewModel的OnCleared结束ViewModel的一生。这个原因在FragmentActivity中找到了答案,之前说过ViewModelProvider的属性ViewModelStore是通过传入的ViewModelStoreOwner中getViewModelStore()方法获取的,FragmentActivity源码中getViewModelStore()可以看到
NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); if (nc != null) { // Restore the ViewModelStore from NonConfigurationInstances mViewModelStore = nc.viewModelStore; }了然,当配置发生变化时会自动保存viewModelStore,在恢复后如果发现是配置变化就使用之前的viewModelStore,viewModelStore没变,其内保存各个VIewModel的Map也就不会变
由于每个Activity传入的ViewModelStoreOwner不同,所以即使它们有相同的ViewModel其内数据也不同Fragment传入的getActivity代表了,一个Activity上所有的Fragment都是共用一个ViewModelStore,也就表明两个fragment之间可以通过使用相同的ViewModel来共享数据之前一直疑惑为什么要用Map来存,讲道理一个Activity使用一个ViewModel就好,如果有多个数据,比如UserLiveData和SettingsLiveData只要把它们都放在同一个ViewModel就好。个人见解:原因1解耦,不想把不同数据的操作放在一起;原因2性能,这样设计的原因是为了Fragment使用,一个Activity上可能有多个Fragment,而每个Fragment里面有不同的数据可能性很小,所以间接可以理解为每个Fragment对应一个ViewModel各自管理各自的数据,而所有这些ViewModel都放在一个Map里面共享。