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

<T extends ViewModel> T create(@NonNull Class<T> 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<Activity, HolderFragment> mNotCommittedActivityHolders = new HashMap<>();
private Map<Fragment, HolderFragment> mNotCommittedFragmentHolders = new HashMap<>();

可以看到核心功能的实现都在这里了,findHolderFragment和createHolderFragment两个方法也很简单,前者查找是不是已经有这个HolderFragment了,如果没有则调用后者创建一个HolderFragment,并add fragment;然后分别监听了Activity和Fragment的生命周期,实现了ViewModel共享和及时销毁。

registerActivityLifecycleCallbacks和registerFragmentLifecycleCallbacks也是lifecycle工作能力的核心逻辑,这里略过。

最后看下ViewModelProvider的get方法

    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);
    }

    @NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> 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,并监听生命周期,完成了数据共享和生命周期可控。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值