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
-
@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);
}
/**
*/
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 的死亡:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。