ViewModel将视图数据和逻辑的所有权与像Activities和Fragments这样与生命周期绑定的实体分离开来。ViewModel不仅消除了常见的生命周期问题,还有助于构建更模块化且更易于测试的UI。 Activity或Fragment可以通过LiveData或Android Data Binding观察ViewModel中的更改。 注意:ViewModel的唯一责任是管理UI的数据。它不应访问你的视图层次结构或持有对Activity或Fragment的引用。
/** * Utilities methods for {@link ViewModelStore} class. */ publicclassViewModelProviders { /** * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given Activity * is alive. More detailed explanation is in {@link ViewModel}. * <p> * It uses {@link ViewModelProvider.AndroidViewModelFactory} to instantiate new ViewModels. * * @param activity an activity, in whose scope ViewModels should be retained * @return a ViewModelProvider instance */ @NonNull @MainThread publicstatic ViewModelProvider of(@NonNull FragmentActivity activity) { ViewModelProvider.AndroidViewModelFactoryfactory= ViewModelProvider.AndroidViewModelFactory.getInstance( checkApplication(activity)); returnnewViewModelProvider(ViewModelStores.of(activity), factory); } }
/** * {@link Factory} which may create {@link AndroidViewModel} and * {@link ViewModel}, which have an empty constructor. */ publicstaticclassAndroidViewModelFactoryextendsViewModelProvider.NewInstanceFactory {
privatestatic AndroidViewModelFactory sInstance;
/** * Retrieve a singleton instance of AndroidViewModelFactory. * * @param application an application to pass in {@link AndroidViewModel} * @return A valid {@link AndroidViewModelFactory} */ publicstatic AndroidViewModelFactory getInstance(@NonNull Application application) { if (sInstance == null) { sInstance = newAndroidViewModelFactory(application); } return sInstance; }
private Application mApplication;
/** * Creates a {@code AndroidViewModelFactory} * * @param application an application to pass in {@link AndroidViewModel} */ publicAndroidViewModelFactory(@NonNull Application application) { mApplication = application; }
@NonNull @Override public <T extendsViewModel> T create(@NonNull Class<T> modelClass) { if (AndroidViewModel.class.isAssignableFrom(modelClass)) { //noinspection TryWithIdenticalCatches try { return modelClass.getConstructor(Application.class).newInstance(mApplication); } catch (NoSuchMethodException e) { thrownewRuntimeException("Cannot create an instance of " + modelClass, e); } catch (IllegalAccessException e) { thrownewRuntimeException("Cannot create an instance of " + modelClass, e); } catch (InstantiationException e) { thrownewRuntimeException("Cannot create an instance of " + modelClass, e); } catch (InvocationTargetException e) { thrownewRuntimeException("Cannot create an instance of " + modelClass, e); } } returnsuper.create(modelClass); } }
//initializing the custom factory class MyViewModelFactoryfactory=newMyViewModelFactory(data1, data2); ViewModelProviders.of(this, factory).get(MyViewModel.class);
/** * Returns the {@link ViewModelStore} of the given activity. * * @param activity an activity whose {@code ViewModelStore} is requested * @return a {@code ViewModelStore} */ @NonNull @MainThread publicstatic ViewModelStore of(@NonNull FragmentActivity activity) { if (activity instanceof ViewModelStoreOwner) { return ((ViewModelStoreOwner) activity).getViewModelStore(); } return holderFragmentFor(activity).getViewModelStore(); }
/** * Returns the {@link ViewModelStore} of the given fragment. * * @param fragment a fragment whose {@code ViewModelStore} is requested * @return a {@code ViewModelStore} */ @NonNull @MainThread publicstatic ViewModelStore of(@NonNull Fragment fragment) { if (fragment instanceof ViewModelStoreOwner) { return ((ViewModelStoreOwner) fragment).getViewModelStore(); } return holderFragmentFor(fragment).getViewModelStore(); } }
/** * Class to store {@code ViewModels}. * <p> * An instance of {@code ViewModelStore} must be retained through configuration changes: * if an owner of this {@code ViewModelStore} is destroyed and recreated due to configuration * changes, new instance of an owner should still have the same old instance of * {@code ViewModelStore}. * <p> * If an owner of this {@code ViewModelStore} is destroyed and is not going to be recreated, * then it should call {@link #clear()} on this {@code ViewModelStore}, so {@code ViewModels} would * be notified that they are no longer used. * <p> * {@link android.arch.lifecycle.ViewModelStores} provides a {@code ViewModelStore} for * activities and fragments. */ publicclassViewModelStore {
final ViewModel get(String key) { return mMap.get(key); }
/** * Clears internal storage and notifies ViewModels that they are no longer used. */ publicfinalvoidclear() { for (ViewModel vm : mMap.values()) { vm.onCleared(); } mMap.clear(); } }
/** * A scope that owns {@link ViewModelStore}. * <p> * A responsibility of an implementation of this interface is to retain owned ViewModelStore * during the configuration changes and call {@link ViewModelStore#clear()}, when this scope is * going to be destroyed. */ @SuppressWarnings("WeakerAccess") publicinterfaceViewModelStoreOwner { /** * Returns owned {@link ViewModelStore} * * @return a {@code ViewModelStore} */ @NonNull ViewModelStore getViewModelStore(); }