zoukankan      html  css  js  c++  java
  • Android Jetpack -- ViewModel篇(一)

    ViewModel的出现主要为了解决两个问题:
    1.当Actvitiy销毁重建过程中的数据恢复问题,虽然原来可以使用onSaveInstanceState()来完成,但是只支持能被序列化的数据而且是小量数据,对于大量数据则显得有点无力。
    2.UI控制器的工作繁忙,UI控制器主要用于处理显示,交互,其他的额外操作可以委托给其他类完成,将不应该分配给UI的任务分离出来是必要的,这也就是上面所说的分离关注点原则。
    下面是示意图

    ViewModel实例

    ViewModel在配置更改期间能自动保留其对象,以便它们所持有的数据可立即用于下一个 Activity 或片段 Fragment

    具体的实例我在以前的一篇博客中讲过了,想要了解请点击  Android学习进度二  进行查看。

    回到最上面的那个图,图说明了ViewModel的作用域涉及到整个生命周期,当获取ViewModel时,ViewModel的生命周期限定为传入ViewModelProvider的对象的生命周期。也就是对于以下场景(引用官方示例)

        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 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.
                 });
             }
         }
         

    由于传入的是Activity,所以其作用域为整个Activity,不同的Fragment可以通过ViewModelProviders获取到同一个ViewModel,这样有以下的好处:

    • Activity无须参与Fragment之间的交互。Activity与Fragment无关
    • Fragment之间也无需互相建立联系,Fragment与Fragment无关
    • 每个Fragment都有自己的生命周期,即使被替换也不会有任何影响

    ViewModel加强,支持异常生命周期

    有些时候在Activity被意外杀死,如清理后台等会直接跳过onDestory()而是回调onSaveInstanceState()异常杀死下的生命周期,这个时候ViewModel也会被杀死,再次恢复的时候便会被重建,这样,原来的数据也就丢失了,因此我们需要改进一下ViewModel以支持异常退出情况下的重建。
    首先很容易是想到通过onSaveInstanceState() 来保存,然后通过SaveInstanceState 来恢复,虽然也是一种可行的方法,但是跟ViewModel没什么关联,ViewModel也提供了类似SavedInstanceState的方法。

    SavedStateHandle :用于保存状态的数据类型,是一个key-value的map,类似于Bundle。

    具体用法

     public class ViewModelWithData extends ViewModel {
     
         private MutableLiveData<Integer> number;
         private SavedStateHandle handle;
     
         private static final String KEY_NUMBER = "number";
     
         public ViewModelWithData(SavedStateHandle handle) {
             this.handle = handle;
             number = new MutableLiveData<>();
             number.setValue(0);
         }
     
         public MutableLiveData<Integer> getNumber() {
             if (!handle.contains(KEY_NUMBER)) {
                 handle.set(KEY_NUMBER, 0);
             }
             return handle.getLiveData(KEY_NUMBER);
         }
     
         public void addNumber(int n) {
             getNumber().setValue(getNumber().getValue() + n);
         }
     }
     public class LiveDataActivity extends AppCompatActivity {
     
         private ViewModelWithData viewModelWithData;
     
         ActivityLiveDataBinding binding;
     
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             binding = DataBindingUtil.setContentView(this, R.layout.activity_live_data);
             viewModelWithData = ViewModelProviders.of(this, new SavedStateVMFactory(this)).get(ViewModelWithData.class);
             binding.setData(viewModelWithData);
             binding.setLifecycleOwner(this);
         }
     
     }
  • 相关阅读:
    C——联合体(共同体)总结
    JMX操作ActiveMQ(1)
    使用xml和java代码混合控制UI界面
    Hive Metastore ObjectStore PersistenceManager自动关闭bug解析
    (算法课大报告)大数据的查找与排序
    编程珠玑---读书笔记---使用后缀数组查找最长重复子串
    VMware vSphere服务器虚拟化实验十一高可用性之三Fault Tolerance
    签名应用例子
    fopen()惹的祸
    Bigcommerce: 给已完成购买的客户发送一封产品评论邮件,让客户直接进行产品评论
  • 原文地址:https://www.cnblogs.com/best-hym/p/12200661.html
Copyright © 2011-2022 走看看