ViewModel
的职责是为Activity
或者Fragment
管理数据.java
ViewModel
或者AndroidViewModel
class MyViewModel : ViewModel(){ } //若是你须要在ViewModel中使用上下文对象,能够继承AndroidViewModel class MyViewModel2(var application : Application) : AndroidViewModel(){ }
若是继承AndroidViewModel
,构造函数必须有一个Application
类型的参数,而且只能是Application
,而不是其子类.
Activity
或者Fragment
中获取MyViewModel
实例对象val myViewModel = ViewModelProviders.of(activity/fragment).get(MyViewModel::class.java)
public static ViewModelProvider of(@NonNull Fragment fragment) { return of(fragment, null); } public static ViewModelProvider of(@NonNull FragmentActivity activity) { return of(activity, null); }
这里只看Activity的android
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(ViewModelStores.of(activity), factory); }
看一下ViewModelProvider这个构造函数架构
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) { mFactory = factory; this.mViewModelStore = store; }
当获取到ViewModelProvider对象后,调用其get方法获取到MyViewModel的实例对象
看一下get方法app
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"); } return get(DEFAULT_KEY + ":" + canonicalName, modelClass); } public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) { //从ViewModelStore中获取ViewModel对象 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); mViewModelStore.put(key, viewModel); //noinspection unchecked return (T) viewModel; }
从这里能够看到是从ViewModelStore中获取ViewModel对象.在ViewModelStore中封装了一个HashMap对象.若是HashMap对象中存储了ViewModel对象,就直接复用,若是ViewModel对象未建立,就从新建立后存储在HashMap中.ide
要保证ViewModel是惟一的,ViewModelStore就必须是惟一的.看一下ViewModelStore是若是获取到的.
在给ViewModelProvider传参数时调用了ViewModelStores.of(activity),看一下这一步作了什么?函数
//ViewModelStores.java public static ViewModelStore of(@NonNull FragmentActivity activity) { if (activity instanceof ViewModelStoreOwner) { return ((ViewModelStoreOwner) activity).getViewModelStore(); } return holderFragmentFor(activity).getViewModelStore(); }
查看安卓源码发现,support包下的Fragment和FragmentActivity都继承了ViewModelStoreOwner,天然要实现其方法.post
//FragmentActivity 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) { FragmentActivity.NonConfigurationInstances nc = (FragmentActivity.NonConfigurationInstances)this.getLastNonConfigurationInstance(); if (nc != null) { this.mViewModelStore = nc.viewModelStore; } if (this.mViewModelStore == null) { this.mViewModelStore = new ViewModelStore(); } } return this.mViewModelStore; } }
能够看出,对于一个未销毁的Activity或者Fragment,其ViewModelStore对象是惟一的.那么其存储的ViewModel对象也是惟一的.this
由上面可知,Activity或者Fragment未被销毁,ViewModel是惟一的,那么其保存的数据也是不变的,当Activity发生了屏幕旋转等变化时,仍旧能够复用ViewModel中的数据.google
ViewModel内部不要持有View
层的引用,好比Activity
或者Fragment
.能够和LiveData
结合使用spa
由图可看出,Activity重建先后,ViewModel保持不变.
LiveData
持有数据,并可在给定的生命周期内被观测.
继承关系以下:
[LiveData] ^- [MutableLiveData] ^- [MediatorLiveData] MutableLiveData
对外暴露setValue
和postValue
.MediatorLiveData
观察别的LiveData
.并能将active/inactive
状态传递给它所观察的LiveData
对象.
postValue
能够从后台线程更新数据,setValue
只能在主线程中更新数据.若是同时调用这两个方法,postValue
设置的数据会覆盖code>setValue设置的数据.postValue
是经过ArchTaskExecutor
来实如今主线程中更新数据.在ArchTaskExecutor
中使用主线程的Handler
.
若是一个观察者经过observeForever
被添加,这个观察者会被认为一直处于激活状态,任何数据更新都会当即通知到它.所以须要手动调用removeObserver
去移除它.
v4包下的SupportActivity
和Fragment
默认都实现了LifecycleOwner(<font color='#ff0000' size='6px'>API27+</font>),而且都默认初始化了lifeCycle实例
//LifecycleOwner public interface LifecycleOwner { /** * Returns the Lifecycle of the provider. * * @return The lifecycle of the provider. */ @NonNull Lifecycle getLifecycle(); } //supportActivity public class SupportActivity extends Activity implements LifecycleOwner, Component { private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); public Lifecycle getLifecycle() { return this.mLifecycleRegistry; } } public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner, ViewModelStoreOwner { LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } } public class LifecycleRegistry extends Lifecycle { //......... }
若是你使用的是java8,能够经过添加如下依赖来使用DefaultLifecycleObserver
android.arch.lifecycle:common-java8:<version>
而后实现DefaultLifecycleObserver
class TestObserver implements DefaultLifecycleObserver { @Override public void onCreate(LifecycleOwner owner) { // your code } }
若是使用的是java7,经过注解来监听生命周期事件.而且能够给对用的生命周期方法添加一个LifecycleOwner
参数.若是方法被Lifecycle.Event.ON_ANY
注解,那么该方法能够额外添加一个Lifecycle.Event.ON_ANY
参数.
class TestObserver implements LifecycleObserver { @OnLifecycleEvent(ON_CREATE) void onCreated(LifecycleOwner source) {} @OnLifecycleEvent(ON_ANY) void onAny(LifecycleOwner source, Event event) {} }
由图能够看出,无论数据从哪里来,最终要汇聚到数据仓库,LiveData
观察的是数据仓库的变化.而且ViewModel
中能够定义多个LiveData
.