简单分析ViewModel源码

先从使用的代码开始:

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用来管理ViewModel,而Factory更简单,只有一个方法用来创建ViewModel:

 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,并监听生命周期,完成了数据共享和生命周期可控。

你可能感兴趣的:(android源码分析)