Android jetpack - ViewModel

简介

以生命周期的方式存储和管理界面相关的数据,从界面控制器逻辑中分离出视图数据所有权,让代码更易行且更高效

使用方式

  1. 自定义ViewModel (ViewModel不需要额外引入其他配置),直接继承ViewModel,如果自定义的viewmodel需要使用context,可继承自AndroidViewModel,这里面会维护ApplicationContext,不要将Activity中context或者其他context传入ViewModel,因为ViewModel的生命周期比Activity或者Fragment长,如果引用它们的Context会造成内存泄漏
class VodViewModel : ViewModel() {
//一般配合LiveData使用
    private val movies: MutableLiveData<List<Movie>> by lazy {
        MutableLiveData().also {
            loadMovies()
        }
    }

    fun getMovies(): LiveData<List<Movie>> {
        return movies
    }

    private fun loadMovies() {
        // 执行数据加载,一般是网络请求
    }
}

class LiveViewModel : ViewModel() {
    private val movies: MutableLiveData<List<Movie>> by lazy {
        MutableLiveData().also {
            loadMovies()
        }
    }

    fun getMovies(): LiveData<List<Movie>> {
        return movies
    }

    private fun loadMovies() {
        // 执行数据加载,一般是网络请求
    }
}
  1. 在Activity或fragment中使用,一般在onCreate方法中调用,一旦调用viewModel就会被实例化,直至Activity或fragment被销毁后自动调用onCleared()解除
ViewModelProvider viewModelProvider = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory());
VodViewModel vodViewModel = viewModelProvider.get(VodViewModel.class);
//配合LiveData使用即可在数据发生变化时自动更新界面
vodViewModel.getMovies().observe(this, movies -> {
	// update UI
});
LiveViewModel liveViewModel = viewModelProvider.get(LiveViewModel.class);
liveViewModel.getMovies().observe(this, movies -> {
	// update UI
});

注:

  1. ViewModelProvider(ViewModelStoreOwner owner, Factory factory),使用这个构造参数创建了ViewModelProvider,再通过ViewModelProvider的get方法获取想要的viewModel,所以传入的this(即Activity或者Application)需要继承自ViewModelStoreOwner,如果你的Activity继承自AppCompatActivity或者FragmentActivity就不需要管,因为它们默认已经实现了ViewModelStoreOwner接口

  2. 传入的第一个参数ViewModelStoreOwner即将当前界面控制器与ViewModelProvider进行了绑定,ViewModelProvider内部有一个属性ViewModelStore就是通过ViewModelStoreOwner.getViewModelStore()获取的,ViewModelStore里维护一个HashMap,即存储当前界面控制器需要观察的所有ViewModel,在界面控制器销毁时调用ViewModelStore的clear方法,在这里对map里面所有的ViewModel执行onCleared,然后清空map

  3. 当配置发生变化时虽然Activity调用了onDestroy方法但是ViewModel还是之前的ViewModel,而真正销毁时调用的onDestroy就会调用ViewModel的OnCleared结束ViewModel的一生。这个原因在FragmentActivity中找到了答案,之前说过ViewModelProvider的属性ViewModelStore是通过传入的ViewModelStoreOwner中getViewModelStore()方法获取的,FragmentActivity源码中getViewModelStore()可以看到

NonConfigurationInstances nc =
		(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
	// Restore the ViewModelStore from NonConfigurationInstances
	mViewModelStore = nc.viewModelStore;
}

了然,当配置发生变化时会自动保存viewModelStore,在恢复后如果发现是配置变化就使用之前的viewModelStore,viewModelStore没变,其内保存各个VIewModel的Map也就不会变

  1. 由于每个Activity传入的ViewModelStoreOwner不同,所以即使它们有相同的ViewModel其内数据也不同
  2. Fragment传入的getActivity代表了,一个Activity上所有的Fragment都是共用一个ViewModelStore,也就表明两个fragment之间可以通过使用相同的ViewModel来共享数据
  3. 之前一直疑惑为什么要用Map来存,讲道理一个Activity使用一个ViewModel就好,如果有多个数据,比如UserLiveData和SettingsLiveData只要把它们都放在同一个ViewModel就好。个人见解:原因1解耦,不想把不同数据的操作放在一起;原因2性能,这样设计的原因是为了Fragment使用,一个Activity上可能有多个Fragment,而每个Fragment里面有不同的数据可能性很小,所以间接可以理解为每个Fragment对应一个ViewModel各自管理各自的数据,而所有这些ViewModel都放在一个Map里面共享。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Jetpack是Google提供的一套用于加速Android应用开发的工具包,其中包括了许多架构组件,其中之一就是ViewModelViewModel是一种设计模式,用于保存和管理与UI相关的数据。在传统的Android开发中,当屏幕旋转或者因为其他原因导致Activity或Fragment重建时,之前保存的临时数据就会丢失。而ViewModel的出现解决了这个问题。 ViewModel的主要作用是将数据与UI组件分离。它的工作方式是创建一个ViewModel类,并在其中保存需要与UI组件交互的数据。这样,当屏幕旋转或重建时,ViewModel实例不会销毁,数据也会得到保留。然后,在Activity或Fragment中,通过获取ViewModel实例,可以轻松地访问这些数据。 使用ViewModel的好处有很多。首先,它可以避免内存泄漏,因为ViewModel的生命周期与Activity或Fragment无关。其次,它可以节省资源,因为当Activity或Fragment销毁时,ViewModel实例可以被系统缓存起来,下次再创建时可以直接返回该实例。另外,由于ViewModel保存了与UI相关的数据,可以减少因为屏幕旋转导致的数据重复加载的问题。 在使用ViewModel时,你可以选择使用Android Jetpack中的其他架构组件来进一步提高开发效率,比如通过LiveData实现数据的观察和通知,或者通过DataBinding来实现UI与数据的自动绑定。 总之,ViewModelAndroid Jetpack中非常重要的一个架构组件,它的出现实现了数据与UI的解耦,提高了开发效率,并且解决了数据丢失的问题。希望通过这篇文档的详解,你对ViewModel有了更深入的理解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值