Android Jetpack -- ViewModel篇(一)

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

ViewModel实例

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

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

 

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

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,这样有如下的好处:spa

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

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

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

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

具体用法对象

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);   }  
 }
相关文章
相关标签/搜索