深入了解架构组件之ViewModel,android高级面试题汇总

public class DetailFragment extends Fragment {

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

model.getSelected().observe(this, { item ->

// Update the UI.

});

}

}

仔细体会下这样的好处会发现:

1、Activity 不需要做任何事,甚至不知道这次交互,完美解耦。

2、Fragment 只需要 与ViewModel交互,不需要知道对方 Fragment 的状态甚至是否存在,更不需要持有其引用。所有当对方 Fragment 销毁时,不影响本身任何工作。

3、Fragment 生命周期互不影响,甚至 fragment 替换成其他的 也不影响这个系统的运作。

二、用法简介

======

ViewModel一般配合 LiveData 使用,LiveData可以参考我另一篇文章

首先,获取 ViewModel 实例,通过提供的类ViewModelProviders:

MyViewModel model = ViewModelProviders.of(activity).get(MyViewModel.class);

MyViewModel model = ViewModelProviders.of(fragment).get(MyViewModel.class);

或带有 Factory 的

MyViewModel model = ViewModelProviders.of(activity,factory).get(MyViewModel.class);

VM 内部操作:

public class MyViewModel extends ViewModel {

private MutableLiveData<List> users;

public LiveData<List> getUsers() {

if (users == null) {

users = new MutableLiveData<List>();

loadUsers();

}

return users;

}

private void loadUsers() {

// Do an asynchronous operation to fetch users.

}

}

深入了解架构组件之ViewModel,android高级面试题汇总

然后,可在 activity 观察数据变化:

public class MyActivity extends AppCompatActivity {

public void onCreate(Bundle savedInstanceState) {

// Create a ViewModel the first time the system calls an activity’s onCreate() method.

// Re-created activities receive the same MyViewModel instance created by the first activity.

MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);

model.getUsers().observe(this, users -> {

// update UI

});

}

}

三、源码分析原理

========

先从 ViewModel 生命周期开始的时刻着手分析,那么什么时候开始的呢?废话,当然是从我们实例化它开始,那么我们什么时候实例化呢,官网的原话是:

You usually request a ViewModel the first time the system calls an activity object’s onCreate() method.

没错,我们一般在 onCreate 里初始化。

ViewModel 的出生:

实例化的代码很简单,我们慢慢剖析,做了哪些事情

ViewModelProviders.of(activity,factory).get(MyViewModel.class)

1、 首先是ViewModelProviders 的 of 方法:

@MainThread

public static ViewModelProvider of(@NonNull FragmentActivity activity) {

initializeFactoryIfNeeded(checkApplication(activity));

return new ViewModelProvider(ViewModelStores.of(activity), sDefaultFactory);

}

@MainThread

public static ViewModelProvider of(@NonNull FragmentActivity activity,

@NonNull Factory factory) {

checkApplication(activity);

return new ViewModelProvider(ViewModelStores.of(activity), factory);

}

参数有 activity 与 fragment 的我就只贴 activity 的了 ,重点看这里引出了一个 Factory,不带Factory的方法只是通过initializeFactoryIfNeeded初始化了一个sDefaultFactory(Factory的实现类):

/**

  • Implementations of {@code Factory} interface are responsible to instantiate ViewModels.

*/

public interface Factory {

/**

  • Creates a new instance of the given {@code Class}.

  • @param modelClass a {@code Class} whose instance is requested

  • @param The type parameter for the ViewModel.

  • @return a newly created ViewModel

*/

@NonNull

T create(@NonNull Class modelClass);

}

只有一个 create 方法,用脚指头想想也知道肯定是用来初始化viewmodel的。先放着里等会用到再说。继续看 of 方法:

return new ViewModelProvider(ViewModelStores.of(activity), sDefaultFactory)

出现了两个新的类ViewModelProvider与ViewModelStores,先看ViewModelProvider:

public class ViewModelProvider {

private static final String DEFAULT_KEY =

“android.arch.lifecycle.ViewModelProvider.DefaultKey”;

private final Factory mFactory;

private final ViewModelStore mViewModelStore;

……

@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;

}

}

多余的都省略了,此类很简单 就是维护了 一个mFactory,一个新出现的类ViewModelStore(待会会讲),并提供了用mFactory和ViewModelStore生成 ViewModel 的 get 方法。哇,这里就已经看到 ViewModel 最终实例化的地方了,但是别着急还有好多东西呢。

再来看

ViewModelStores.of(activity)

干了啥。先看ViewModelStores:

/**

  • Factory methods for {@link ViewModelStore} class.

*/

@SuppressWarnings(“WeakerAccess”)

public class ViewModelStores {

private ViewModelStores() {

}

/**

  • Returns the {@link ViewModelStore} of the given activity.

  • @param activity an activity whose {@code ViewModelStore} is requested

  • @return a {@code ViewModelStore}

*/

@MainThread

public static ViewModelStore of(@NonNull FragmentActivity activity) {

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}

*/

@MainThread

public static ViewModelStore of(@NonNull Fragment fragment) {

return holderFragmentFor(fragment).getViewModelStore();

}

}

只有两个 of 方法,holderFragmentFor为 HolderFragment 初始化的静态方法, 剧透一下HolderFragment 发挥了至关重要的作用,这里先不讲其重要作用 只看getViewModelStore()

public class HolderFragment extends Fragment {

……

private ViewModelStore mViewModelStore = new ViewModelStore();

public ViewModelStore getViewModelStore() {

return mViewModelStore;

}

……

}

没啥说的,看ViewModelStore:

public class ViewModelStore {

private final HashMap<String, ViewModel> mMap = new HashMap<>();

final void put(String key, ViewModel viewModel) {

ViewModel oldViewModel = mMap.get(key);

if (oldViewModel != null) {

oldViewModel.onCleared();

}

mMap.put(key, viewModel);

}

final ViewModel get(String key) {

return mMap.get(key);

}

/**

  • Clears internal storage and notifies ViewModels that they are no longer used.

*/

public final void clear() {

for (ViewModel vm : mMap.values()) {

vm.onCleared();

}

mMap.clear();

}

}

很明显是一个用来存放 ViewModel 实例的类,内部维护了一个 HashMap 存放 ViewModel,

并提供了 get,put,clear方法。

至此ViewModelProviders of 做了哪些事情呢:

1、初始化了ViewModelProvider内部维护了 用于创建 VM 的 Factory,和用户存放 VM 的ViewModelStore;

2、初始化了 用来生成 ViewModel 的 Factory(默认为DefaultFactory);

3、通过ViewModelStores的静态方法实例化了 HolderFragment,并实例化了ViewModelStore

2、然后是ViewModelProvider的 get 方法:

上面已经贴过了,再贴一下吧:

ViewModelProviders.of(activity,factory).get(MyViewModel.class);

@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;

}

逻辑不复杂,先看ViewModelStore是不是已经存了,没有的话就通过 factory 实例化, 并存到 ViewModelStore 中。

ViewModel 的死亡:

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;

}

逻辑不复杂,先看ViewModelStore是不是已经存了,没有的话就通过 factory 实例化, 并存到 ViewModelStore 中。

ViewModel 的死亡:

上一篇:JectPack组件原理分析 ---- ViewModel


下一篇:计算机网络漫谈:OSI七层模型与TCP/IP四层(参考)模型