深入了解架构组件之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.
}
}
然后,可在 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 的死亡:
标签:面试题,ViewModel,get,viewModel,ViewModelStore,activity,android,public 来源: https://blog.csdn.net/m0_66265052/article/details/122747047