ViewModel如何使用

发布时间:2022-01-11 17:19:00 作者:iii
来源:亿速云 阅读:191

这篇文章主要介绍“ViewModel如何使用”,在日常操作中,相信很多人在ViewModel如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ViewModel如何使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1 主要功能

2 使用方法

1) 引入ViewModel

  1. 在build.gradle中添加编译lifecycle.extensions module,该module同时包含ViewModel和LiveData:

compile('android.arch.lifecycle:extensions:1.0.0')

由于lifecycle.extensions内部依赖26.1.0版本的support_v7包,建议将工程中已引用的support_v7组件版本也升级到26.1.0或以上。

2) 构造数据对象

  1. 自定义ViewModel类,继承ViewModel;

  2. 在自定义的ViewModel类中添加需要的数据对象;

public class DemoViewModel extends ViewModel { 
    final public DemoData mData = new DemoData(); 
    public DemoViewModel() {} 
}

3) 获取数据

  1. 通过ViewModelProviders和Activity / Fragment获取ViewModelProvider;

  2. 通过ViewModelProvider和自定义ViewModel类获取自定义ViewModel对象;

  3. 从自定义ViewModel对象获取数据对象,进行需要的读写操作。

DemoData data = ViewModelProviders.of(getActivity()) 
        .get(DemoViewModel.class)
        .mData; 
data.doSth();

3 使用场景示范

1) 单Activity多Fragment间数据维护

麻烦且数据大小有限制。

同样麻烦,且有一定风险。

ViewModel同时规避了传统方法的缺点:

2) 与LiveData配合实现UI、业务逻辑分层

同为官方架构组件的LiveData,功能是监听数据变化,并回调给注册的observer。ViewModel+LiveData可以很方便的抽象出数据层和业务层,快速解耦。
下面的Demo来自官方案例。通过Demo,以及LiveData、ViewModel同处一个module,可以看出官方非常建议两者搭配使用。再配合以往的Data-Binding,可以快速搭建起一套简易的MVVM业务体系。

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 an asyncronous operation to fetch users. 
    } 
} 
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 thefirst activity. 
          MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class); 
          model.getUsers().observe(this,users -> { 
                //update UI 
          });
     } 
}

4 生命周期特性

ViewModel的生命周期与Lifecycle同步,当Activity /Fragment超出Lifecycle范围(并不是onDestroy()回调),ViewModel连同其包含的数据一起被销毁了。具体有多大呢,按照官方说法:

in the case of an activity, when it finishes, whilein the case of a fragment, when it’s detached.

Activity退栈后(Fragment则是与Activity解除关系后),ViewModel就解除引用关系,准备被系统回收了。

5 源码分析

带着两个小问题简单的进行下源码分析:

1)    ViewModel与Activity / Fragment的映射关系是如何建立起来的?

(以Activity为例)

第一部分:获取ViewModelProvider

HolderFragment.class 
HolderFragment holderFragmentFor(FragmentActivity activity) { 
     FragmentManagerfm = activity.getSupportFragmentManager(); 
     HolderFragment holder = findHolderFragment(fm); 
     if(holder != null) { 
            return holder; 
      }else { 
            holder = (HolderFragment)this.mNotCommittedActivityHolders.get(activity); 
            if(holder != null) { 
                  return holder; 
            }else { 
                 //创建HolderFragment

第一部分的职责是构建 / 查找HolderFragment,对构建过程中的异常做保护,最后返回ViewModelProvider。HolderFragment和ViewModelProvider共同持有的ViewModelStore将成为第二部分的核心;

(第二部分:获取ViewModel)

ViewModelStore.class 
public class ViewModelStore { 
  private final HashMap<String, ViewModel> mMap = new HashMap();

第二部分职责是映射,通过类名从HashMap查找ViewModel实例。整个映射逻辑也可以简化为:通过Activity类名找ViewModel实例;

2) ViewModel的生命周期如何管理?

ViewModel objects are scoped to the Lifecycle passed to the ViewModelProvider when getting the ViewModel.

看到官方文档中的这句话,心想ViewModel莫非是通过同为官方架构组件的Lifecycle来管理的生命周期的?
其实并没有那么复杂,ViewModel在第一次调用ViewModelProvider.get(ViewModel.class)创建;而销毁就需要靠HolderFragment自己的onDestroy()回调:

HolderFragment.class 
public void onDestroy() { 
        super.onDestroy();        
        this.mViewModelStore.clear();
}
ViewModelStore.class 
public final void clear() { 
        Iteratorvar1 = this.mMap.values().iterator(); 
        while(var1.hasNext()){ 
            ViewModel vm = (ViewModel)var1.next(); 
            vm.onCleared();
        } 
        this.mMap.clear();
    }

HolderFragment销毁后,调用ViewModelStore.clear(),清理HashMap对ViewModel对象的引用,待系统GC回收ViewModel。这也解释了创建ViewModelProvider时为什么需要HolderFragment配合,HolderFragment掌控了ViewModel的生命周期。

6 Last but not least

简述下官方架构中各组件的主要职责:

除了Room,可以感受到官方在尽力把大家从最初的MVC往MVVM引导,更加强大的官方组件将使UI-业务-数据的抽象过程变得更加简单顺滑。

到此,关于“ViewModel如何使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

推荐阅读:
  1. JetPack中的LiveData+ViewModel使用
  2. SpringBoot使用NoSQL——Redis的使用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

viewmodel

上一篇:Android的Toast问题有哪些

下一篇:MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决方法是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》