ViewModel源码分析

前面有介绍过ViewModel,主要拥有以下功能特点:

  • 能存储和管理UI相关的数据
  • 并且有自己的一套生命周期

今天谈谈ViewModel的源码分析(基于 V25.3.1 版本)需要涉及的类有:

  • ViewModel
    • 子类 AndroidViewModel
  • ViewModelStore (ViewModel类的管理)
  • ViewModelStoreOwner (提供ViewModelStore的接口)有以下3个类有实现,并在onDestroy清空ViewModelStore
    • Fragment
    • HolderFragment
    • FragmentActivity
  • ViewModelStores (提供获取(FragmentActivity或Fragment)中的ViewModelStore的帮助类)
  • ViewModelProviders (提供获取ViewModelProvider类的)
  • ViewModelProvider (提供获取、创建、缓存 ViewModel;【ViewModelStore的get,put等操作】)


类图

ViewModel 介绍

ViewModel 前面讲过这是一个可以存活在activity,fragment里面的一个数据管理对象,
关于ViewModel 主要有以下两个类

ViewModel源码

  • 一个抽象类
  • 一个构造,一个onCleared()方法
1
2
3
4
5
6
7
public abstract class ViewModel {
public ViewModel() {
}
//ViewModel销毁,生命周期结束调用该方法,可参考ViewModelStore类
protected void onCleared() {
}
}

AndroidViewModel 源码

  • 继承自ViewModel
  • 在ViewModel的基础上,添加了Application属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class AndroidViewModel extends ViewModel {
@SuppressLint({"StaticFieldLeak"})
private Application mApplication;
//构造添加Application 赋值
public AndroidViewModel(@NonNull Application application) {
this.mApplication = application;
}

//兼容自定义Application的情况
@NonNull
public <T extends Application> T getApplication() {
return this.mApplication;
}
}

ViewModelStore 介绍

ViewModelStore是ViewModel类的管理,缓存ViewModel对象,源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class ViewModelStore {
// key ,values 键值对保存数据
private final HashMap<String, ViewModel> mMap = new HashMap();

public ViewModelStore() {
}

// 通过key,保存ViewModel
final void put(String key, ViewModel viewModel) {
ViewModel oldViewModel = (ViewModel)this.mMap.put(key, viewModel);
if (oldViewModel != null) {
//如果存在同名key的ViewModel,结束它。
oldViewModel.onCleared();
}

}

// 通过key,获取ViewModel
final ViewModel get(String key) {
return (ViewModel)this.mMap.get(key);
}

//这个方法一般是,fragment或activity在onDestroy()时调用。 (还有特殊地方:HolderFragment.onDestroy())
public final void clear() {
Iterator var1 = this.mMap.values().iterator();
while(var1.hasNext()) {
ViewModel vm = (ViewModel)var1.next();
vm.onCleared();
}
this.mMap.clear();
}
}

ViewModelStoreOwner 介绍

ViewModelStoreOwner 是提供ViewModelStore的一个接口,源码如下:

1
2
3
4
public interface ViewModelStoreOwner {
@NonNull
ViewModelStore getViewModelStore();
}

该接口在以下三个类中有实现:

Fragment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Fragment implements ViewModelStoreOwner{

ViewModelStore mViewModelStore;

@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (getContext() == null) {
throw new IllegalStateException("Can't access ViewModels from detached fragment");
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
return mViewModelStore;
}

public void onDestroy() {
mCalled = true;
// Use mStateSaved instead of isStateSaved() since we're past onStop()
if (mViewModelStore != null && !mHost.mFragmentManager.mStateSaved) {
mViewModelStore.clear();
}
}

}

HolderFragment

(这个实现感觉有点多余 毕竟上个类Fragment已经实现ViewModelStoreOwner,类似于重写了一遍,使用不慎可能导致ViewModelStore获取的不是同一个)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class HolderFragment extends Fragment implements ViewModelStoreOwner{

private ViewModelStore mViewModelStore = new ViewModelStore();

public void onDestroy() {
super.onDestroy();
this.mViewModelStore.clear();
}

@NonNull
public ViewModelStore getViewModelStore() {
return this.mViewModelStore;
}

}

FragmentActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class FragmentActivity extends BaseFragmentActivityApi16 implements ViewModelStoreOwner{

private ViewModelStore mViewModelStore;

protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
mViewModelStore = nc.viewModelStore;
}
}

@NonNull
@Override
public ViewModelStore getViewModelStore() {
if (getApplication() == null) {
throw new IllegalStateException("Your activity is not yet attached to the "
+ "Application instance. You can't request ViewModel before onCreate call.");
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
return mViewModelStore;
}

boolean mRetaining;
// 该方法调用地方比较多,暂不研究
void doReallyStop(boolean retaining) {
if (!mReallyStopped) {
mReallyStopped = true;
mRetaining = retaining;
mHandler.removeMessages(MSG_REALLY_STOPPED);
onReallyStop();
}
}

//就当默认 !mRetaining = true 即可
@Override
protected void onDestroy() {
super.onDestroy();
doReallyStop(false);
if (mViewModelStore != null && !mRetaining) {
mViewModelStore.clear();
}
}
}

ViewModelStores 类介绍

ViewModelStores 类似一个帮助类,提供获取(FragmentActivity,Fragment)中的 ViewModelStore对象的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ViewModelStores {
private ViewModelStores() {
}

@NonNull
@MainThread
public static ViewModelStore of(@NonNull FragmentActivity activity) {
return activity instanceof ViewModelStoreOwner ? ((ViewModelStoreOwner)activity).getViewModelStore() : HolderFragment.holderFragmentFor(activity).getViewModelStore();
}

@NonNull
@MainThread
public static ViewModelStore of(@NonNull Fragment fragment) {
return fragment instanceof ViewModelStoreOwner ? ((ViewModelStoreOwner)fragment).getViewModelStore() : HolderFragment.holderFragmentFor(fragment).getViewModelStore();
}
}

这个帮助类挺有意思的,需要注意:

  • 如果Fragment,FragmentActivity 实现了ViewModelStoreOwner,就直接获取getViewModelStore()
  • 没有实现ViewModelStoreOwner的类,这种情况,好像还是存在的,这里用了一个中介类,HolderFragment,在内部有HolderFragmentManager类,做了以下事:
    • 提供HolderFragment的方法
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      // 以下两个方法都是获取 添加 HolderFragment的逻辑
      HolderFragment holderFragmentFor(FragmentActivity activity) {
      FragmentManager fm = activity.getSupportFragmentManager();
      // 这里先用FragmentManager查找是否有存在的HolderFragment
      HolderFragment holder = findHolderFragment(fm);
      if (holder != null) {
      // 存在HolderFragment就直接返回
      return holder;
      } else {
      //如果之前缓存过HolderFragment,就从缓存中取
      holder = (HolderFragment)this.mNotCommittedActivityHolders.get(activity);
      if (holder != null) {
      // 缓存中存在HolderFragment就直接返回
      return holder;
      } else {
      // 如果没有监听依赖类销毁就添加一次监听
      if (!this.mActivityCallbacksIsAdded) {
      this.mActivityCallbacksIsAdded = true;
      activity.getApplication().registerActivityLifecycleCallbacks(this.mActivityCallbacks);
      }
      //手动创建HolderFragment,然后缓存
      holder = createHolderFragment(fm);
      this.mNotCommittedActivityHolders.put(activity, holder);
      return holder;
      }
      }
      }

      // Fragment的实现逻辑同上
      HolderFragment holderFragmentFor(Fragment parentFragment) {
      FragmentManager fm = parentFragment.getChildFragmentManager();
      HolderFragment holder = findHolderFragment(fm);
      if (holder != null) {
      return holder;
      } else {
      holder = (HolderFragment)this.mNotCommittedFragmentHolders.get(parentFragment);
      if (holder != null) {
      return holder;
      } else {
      parentFragment.getFragmentManager().registerFragmentLifecycleCallbacks(this.mParentDestroyedCallback, false);
      holder = createHolderFragment(fm);
      this.mNotCommittedFragmentHolders.put(parentFragment, holder);
      return holder;
      }
      }
      }

      //将HolderFragment添加到activity或fragment
      private static HolderFragment createHolderFragment(FragmentManager fragmentManager) {
      HolderFragment holder = new HolderFragment();
      fragmentManager.beginTransaction().add(holder, "android.arch.lifecycle.state.StateProviderHolderFragment").commitAllowingStateLoss();
      return holder;
      }
    • 当父activity或父fragment销毁时从缓存中移除HolderFragment的逻辑,使用了ActivityLifecycleCallbacks,FragmentLifecycleCallbacks两个类
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      private Map<Activity, HolderFragment> mNotCommittedActivityHolders = new HashMap();
      private Map<Fragment, HolderFragment> mNotCommittedFragmentHolders = new HashMap();
      private ActivityLifecycleCallbacks mActivityCallbacks = new EmptyActivityLifecycleCallbacks() {
      public void onActivityDestroyed(Activity activity) {
      HolderFragment fragment = (HolderFragment)HolderFragmentManager.this.mNotCommittedActivityHolders.remove(activity);
      if (fragment != null) {
      Log.e("ViewModelStores", "Failed to save a ViewModel for " + activity);
      }

      }
      };
      private boolean mActivityCallbacksIsAdded = false;
      private FragmentLifecycleCallbacks mParentDestroyedCallback = new FragmentLifecycleCallbacks() {
      public void onFragmentDestroyed(FragmentManager fm, Fragment parentFragment) {
      super.onFragmentDestroyed(fm, parentFragment);
      HolderFragment fragment = (HolderFragment)HolderFragmentManager.this.mNotCommittedFragmentHolders.remove(parentFragment);
      if (fragment != null) {0
      Log.e("ViewModelStores", "Failed to save a ViewModel for " + parentFragment);
      }

      }
      };
    • 检查当前HolderFragment的父activity、父fragment,作移除集合监听操作,该方法在HolderFragment的onCreate中调用(不监听的目的,其实父类的ViewModelStore已经不再使用了)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
       void holderFragmentCreated(Fragment holderFragment) {
      Fragment parentFragment = holderFragment.getParentFragment();
      if (parentFragment != null) {
      this.mNotCommittedFragmentHolders.remove(parentFragment);
      parentFragment.getFragmentManager().unregisterFragmentLifecycleCallbacks(this.mParentDestroyedCallback);
      } else {
      this.mNotCommittedActivityHolders.remove(holderFragment.getActivity());
      }

      }

ViewModelProviders 类介绍

前面讲过通过ViewModelStores类可以获取ViewModelStore类,ViewModelProviders是做什么的呢?

它是用来获取ViewModelProvider类的,在activity、或fragment中,我们一般通过ViewModelProviders这样获取ViewModel:

1
MyViewModel mViewModel = ViewModelProviders.of(this).get(MyViewModel.class);

我们来看看ViewModelProviders的of实现方法吧:

1
2
3
4
5
6
7
8
9
10
11
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment) {
return of((Fragment)fragment, (Factory)null);
}

@NonNull
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity) {
return of((FragmentActivity)activity, (Factory)null);
}

这里又出现了一个新类,是ViewModelProvider的内部类,可以看看实现源码。

Factory

工厂模式,用于生成ViewModel的工厂类,有3个,一个接口,两个实现。

  • Factory
    • NewInstanceFactory 通过反射生成ViewModel
    • AndroidViewModelFactory 通过反射生成AndroidViewModel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//AndroidViewModel工厂
public static class AndroidViewModelFactory extends ViewModelProvider.NewInstanceFactory {

private static ViewModelProvider.AndroidViewModelFactory sInstance;
//需要Application来反射获取AndroidViewModel
private Application mApplication;

@NonNull
public static ViewModelProvider.AndroidViewModelFactory getInstance(@NonNull Application application) {
if (sInstance == null) {
sInstance = new ViewModelProvider.AndroidViewModelFactory(application);
}
return sInstance;
}

public AndroidViewModelFactory(@NonNull Application application) {
this.mApplication = application;
}

@NonNull
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
//如果该类是AndroidViewModel,则直接通过反射生成
if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
try {
return (ViewModel)modelClass.getConstructor(Application.class).newInstance(this.mApplication);
} catch (NoSuchMethodException var3) {
throw new RuntimeException("Cannot create an instance of " + modelClass, var3);
} catch (IllegalAccessException var4) {
throw new RuntimeException("Cannot create an instance of " + modelClass, var4);
} catch (InstantiationException var5) {
throw new RuntimeException("Cannot create an instance of " + modelClass, var5);
} catch (InvocationTargetException var6) {
throw new RuntimeException("Cannot create an instance of " + modelClass, var6);
}
} else {
//不是则,调用父类,生成ViewModel
return super.create(modelClass);
}
}
}

//ViewModel工厂
public static class NewInstanceFactory implements ViewModelProvider.Factory {
public NewInstanceFactory() {
}

@NonNull
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
try {
//通过反射生成ViewModel
return (ViewModel)modelClass.newInstance();
} catch (InstantiationException var3) {
throw new RuntimeException("Cannot create an instance of " + modelClass, var3);
} catch (IllegalAccessException var4) {
throw new RuntimeException("Cannot create an instance of " + modelClass, var4);
}
}
}

//抽象工厂
public interface Factory {
@NonNull
<T extends ViewModel> T create(@NonNull Class<T> var1);
}

继续研究of方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

//通过activity获取Application
private static Application checkApplication(Activity activity) {
Application application = activity.getApplication();
if (application == null) {
throw new IllegalStateException("Your activity/fragment is not yet attached to Application. You can't request ViewModel before onCreate call.");
} else {
return application;
}
}

//通过fragment获取activity
private static Activity checkActivity(Fragment fragment) {
Activity activity = fragment.getActivity();
if (activity == null) {
throw new IllegalStateException("Can't create ViewModelProvider for detached fragment");
} else {
return activity;
}
}

//当前方法或下面方法最终都走了new ViewModelProvider(ViewModelStores.of(fragment), (Factory)factory)
@NonNull
@MainThread
public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) {
Application application = checkApplication(checkActivity(fragment));
if (factory == null) {
factory = AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(ViewModelStores.of(fragment), (Factory)factory);
}

@NonNull
@MainThread
public static ViewModelProvider of(@NonNull FragmentActivity activity, @Nullable Factory factory) {
Application application = checkApplication(activity);
if (factory == null) {
factory = AndroidViewModelFactory.getInstance(application);
}
return new ViewModelProvider(ViewModelStores.of(activity), (Factory)factory);
}

目前截止到如此,ViewModelProvider已获取到,继续研究get方法

  • ViewModelStore 获取到了
  • ViewModelProvider.Factory 获取到了

获取ViewModel还难么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 该方法其实只是为了获取一个key ["android.arch.lifecycle.ViewModelProvider.DefaultKey:" + canonicalName]
// 关键代码如下方法
@NonNull
@MainThread
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");
} else {
return this.get("android.arch.lifecycle.ViewModelProvider.DefaultKey:" + canonicalName, modelClass);
}
}

@NonNull
@MainThread
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
// 通过key 获取 ViewModelStore的ViewModel
ViewModel viewModel = this.mViewModelStore.get(key);
// 判断是不是同类,如果为null,肯定不是啥
if (modelClass.isInstance(viewModel)) {
return viewModel;
} else {
// 这里通过工厂创建一个新的。
viewModel = this.mFactory.create(modelClass);
// 缓存下次待用,完美!!!
this.mViewModelStore.put(key, viewModel);
return viewModel;
}
}

源码研究也就如上了,可以尝试画一个类关系草图,理解起来可能更容易一些。没有美术功底,献丑了。