先从使用的代码开始:
XxxViewModel viewModel = ViewModelProviders.of(FragmentActivity).get(XxxViewModel.class);
XxxViewModel viewModel = ViewModelProviders.of(Fragment).get(XxxViewModel.class);
用法很简单,继承ViewModel然后通过FragmentActivity或者Fragment获取到ViewModelProvider,再根据ViewModel的类获取到ViewModel实例就能实现共享数据了,开始看下怎么实现的呢?
进入ViewModelProviders,发现两个of方法分别有重载方法of(FragmentActivity/Fragment, Factory),最终调用
ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory)
来创建ViewModelProvider,分别看下ViewModelStore和Factory发现都很简单,ViewModelStore持有一个HashMap
T create(@NonNull Class modelClass)
简单说下Factory的实现类,NewInstanceFactory使用无参的构造方法来创建ViewModel,AndroidViewModelFactory继承自NewInstanceFactory,可以构造AndroidViewModel:
if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
//noinspection TryWithIdenticalCatches
try {
return modelClass.getConstructor(Application.class).newInstance(mApplication);
} catch (XxxException e) {
}
}
return super.create(modelClass);
AndroidViewModel继承自ViewModel,多了一个Application成员变量并且构造方法也需要传递Application。
前面说到ViewModelStore很简单,但是创建ViewModelStore的过程就复杂了一些。
public static ViewModelStore of(@NonNull FragmentActivity activity) {
if (activity instanceof ViewModelStoreOwner) {
return ((ViewModelStoreOwner) activity).getViewModelStore();
}
return holderFragmentFor(activity).getViewModelStore();
}
public static ViewModelStore of(@NonNull Fragment fragment) {
if (fragment instanceof ViewModelStoreOwner) {
return ((ViewModelStoreOwner) fragment).getViewModelStore();
}
return holderFragmentFor(fragment).getViewModelStore();
}
可以看到有个接口ViewModelStoreOwner,里面也只定义了一个方法getViewModelStore,这个目前就在jetpack库里有FragmentActivity和Fragment来实现,我在support 27里只看到HolderFragment实现了这个接口。
首先是获取HolderFragment,因为它持有ViewModelStore:
// 首先是调用HolderFragment的静态方法
holderFragmentFor(FragmentActivity activity)
holderFragmentFor(Fragment activity)
// 然后调用了它的内部类HolderFragmentManager的静态方法
HolderFragment holderFragmentFor(FragmentActivity activity) {
FragmentManager fm = activity.getSupportFragmentManager();
HolderFragment holder = findHolderFragment(fm);
if (holder != null) {
return holder;
}
holder = mNotCommittedActivityHolders.get(activity);
if (holder != null) {
return holder;
}
if (!mActivityCallbacksIsAdded) {
mActivityCallbacksIsAdded = true;
activity.getApplication().registerActivityLifecycleCallbacks(mActivityCallbacks);
}
holder = createHolderFragment(fm);
mNotCommittedActivityHolders.put(activity, holder);
return holder;
}
HolderFragment holderFragmentFor(Fragment parentFragment) {
FragmentManager fm = parentFragment.getChildFragmentManager();
HolderFragment holder = findHolderFragment(fm);
if (holder != null) {
return holder;
}
holder = mNotCommittedFragmentHolders.get(parentFragment);
if (holder != null) {
return holder;
}
parentFragment.getFragmentManager()
.registerFragmentLifecycleCallbacks(mParentDestroyedCallback, false);
holder = createHolderFragment(fm);
mNotCommittedFragmentHolders.put(parentFragment, holder);
return holder;
}
// 另外HolderFragmentManager还有2个map来存放HolderFragment
private Map mNotCommittedActivityHolders = new HashMap<>();
private Map mNotCommittedFragmentHolders = new HashMap<>();
可以看到核心功能的实现都在这里了,findHolderFragment和createHolderFragment两个方法也很简单,前者查找是不是已经有这个HolderFragment了,如果没有则调用后者创建一个HolderFragment,并add fragment;然后分别监听了Activity和Fragment的生命周期,实现了ViewModel共享和及时销毁。
registerActivityLifecycleCallbacks和registerFragmentLifecycleCallbacks也是lifecycle工作能力的核心逻辑,这里略过。
最后看下ViewModelProvider的get方法
public T get(@NonNull Class 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);
}
@NonNull
@MainThread
public T get(@NonNull String key, @NonNull Class 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);
mViewModelStore.put(key, viewModel);
//noinspection unchecked
return (T) viewModel;
}
总结一下:总体设计非常精巧和简洁,表面上使用时是通过ViewModelProvider来提供功能,然后它持有的Factory和ViewModelStore分别来创建和管理ViewModel,实际上是通过HolderFragment来管理ViewModelStore,并监听生命周期,完成了数据共享和生命周期可控。