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
.