ViewModel
来源:互联网 发布:ps下载中文版免费 mac 编辑:程序博客网 时间:2024/06/16 06:20
ViewModel是用来保存和操作UI相关的数据的,这样即使configuration发生改变,数据仍然可以存在。
引入ViewModel的原因有三点:
Activity和Fragment等App组件的生命周期都是由系统控制的,是开发者不可控的,保存在其中的数据就有丢失的危险。虽然可以通过onSaveInstanceState()来保存数据,可是这个回调只适合用来保存少量数据比如UI状态,对于一些大量数据比如列表数据就不合适了。
而且Activity和Fragment中都可能进行一些异步操作,这就需要在销毁的时候去清空回调避免内存泄露。或者界面重建后还要重新获取数据,也会浪费资源。
UI控制器本身就负责处理用户交互和系统交互,如果还需要处理数据问题,就会导致职责过多。
所以有必要从UI控制器中抽离出数据的控制权。Lifecycle库提供了ViewModel类用来给UI提供数据。ViewModel不受configuration改变的影响。
ViewModel的示例:
public class MyViewModel extends ViewModel { private MutableLiveData<List<User>> users; public LiveData<List<User>> getUsers() { if (users == null) { users = new MutableLiveData<List<Users>>(); loadUsers(); } return users; } private void loadUsers() { // do async operation to fetch users }}
Activity中的使用:
public class MyActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class); model.getUsers().observe(this, users -> { // update UI }); }}
如果Activity重建了,仍然可以接收到之前Activity所创建的ViewModel。如果该Activity销毁了,ViewModel的onCleared()会被调用,清空资源。
注意:因为ViewModel独立于Activity和Fragment,所以不能引用任何View,或者任何引用了Context 的对象。如果ViewModel需要一个Application类型的Context,可以继承于AndroidViewModel类,构造方法中会有一个Application对象。
在Fragment间分享数据
Fragment间经常需要分享数据,通常是定义接口,然后通过Activity联系在一起。但是Fragment间的生命周期又可能存在不同步,问题就变得比较复杂了。
假设现在有个列表Fragment,还有一个内容Fragment,点击列表Fragment某一项会更新内容Fragment,使用ViewModel可以比较方便地处理数据问题。可以通过Activity获取同一个ViewModel:
public class SharedViewModel extends ViewModel { private final MutableLiveData<Item> selected = new MutableLiveData<Item>(); public void select(Item item) { selected.setValue(item); } public LiveData<Item> getSelected() { return selected; }}public class MasterFragment extends Fragment { private SharedViewModel model; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class); itemSelector.setOnClickListener(item -> { model.select(item); }); }}public class DetailFragment extends LifecycleFragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class); model.getSelected().observe(this, { item -> // update UI }); }}
这样做的好处是:
- Activity不用再负责两个Fragment之间的联系
- Fragment只需要知道ViewModel,不需要知道其他的Fragment,耦合性降低
- 每个Fragment的生命周期相互独立互不影响。
ViewModel的生命周期
ViewModel和SavedInstanceState
ViewModel在Activity的configuration改变过程中可以保持数据不变,但是如果系统把应用杀死掉就没办法了。
如果用户长时间离开应用再进来,应用进程可能已经被系统杀掉了,此时系统会负责恢复之前保存的SavedInstanceState。在onSaveInstanceState()中保存的数据是放在系统进程内存中的,Android系统只允许存放少量的数据,所以最好不要存放一些自定义类的对象进去,可以把自定义对象保存到数据库中,onSaveInstanceState中只保留对象的某个字段比如id,然后再使用ViewModel根据这个id去获取完整的数据。
- ViewModel
- ViewModel
- 理解ViewModel
- MVC ViewModel
- ViewModel [译]
- MVVM 模式 ViewModel
- ViewModel之间的通讯
- 使用ViewModel 模式
- 取得viewModel的name
- MVVM 集合的ViewModel
- Asp.net mvc ViewModel
- viewModel的相关知识
- Android MVVM ViewModel
- Model和ViewModel
- MVC 中的 ViewModel
- 在ViewModel中使用NavigationService在ViewModel中使用NavigationService
- Silverlight + Model-View-ViewModel (MVVM)
- Silverlight + Model-View-ViewModel (MVVM)
- fastcall,stdcall,thiscall,cdecl学习
- Adb常用命令
- 数组、List和ArrayList的区别
- zoj 3957 Knuth-Morris-Pratt Algorithm
- Android零基础入门第22节:ImageView的属性和方法大全
- ViewModel
- 弹出登录框(可直接修改样式使用)
- 利用percona-toolkit中pt-online-schema-change功能对表进行online ddl
- activeMQ深入了解—队列模式手动控制消费
- 操作系统真相还原——MBR
- ajax嵌套
- codeforces B. The number on the board
- Sandcastle Help File Builder[Missing <summary> documentation for ""]
- eclipse远程调试Tomcat方法