Android Jatpack--ViewModel

要点:

①ViewModel负责准备和管理Activity、Fragment等UI相关的数据。

②ViewModel+LiveData可以用于处理Activity、Fragment与应用其他部分的通信,比如调用业务逻辑类。

③由于配置修改(比如旋转屏幕)而导致的Activity重建,不会丢失界面数据。

④ViewModel数据是存储在Activity中的,因此ViewModel还可以用于同一Activity中的多个Fragment间的通信。

 

1.ViewModel

ViewModel是Jetpack的一部分。 ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。

ViewModel出现的背景:

①职责分离

为了能够更好地将职能划分,Android提供了ViewModel类,专门用于存放应用程序页面所需的数据。

②数据保留不丢失

在Android中如果Activity、Fragment销毁或者重建,存储在其中的数据会丢失。对于简单的数据,Activity可以使用onSaveInstanceState()方法来从onCreate()中恢复数据,但这个方法只适合可以序列化再反序列化的少量数据,而不适合较大的数据。

③防止异步操作时内存泄露

UI界面经常需要异步操作,比如网络请求等,当界面销毁时往往需要手动维护异步取消的动作,这样显得特别繁琐,并且把所有代码都写在界面中,会变得特别臃肿。

于是就需要将视图数据与界面分离,让层次清晰且高效。ViewModel作为视图数据和界面的桥梁,用来存储与UI相关的数据,它通过lifecycle感知的方式存储和管理UI相关数据。它可以维护自己的生命周期,不需要手动操作,这无疑大大降低开发难度。

 

ViewModel的生命周期:

be68ea840e704c3c90bde8fe1c56db09.png

这是在没有任何设置的情况下,旋转屏幕时Activity的生命周期变化和ViewModel的生命周期。可以看到旋转屏幕导致Activity重建时,ViewModel中的数据不会被清理。即ViewModel类使得数据在配置更改(如屏幕旋转)时保活。

从这张图可以看出:

①ViewModel的生命周期比创建它的Activity、Fragment的生命周期都要长,即ViewModel中的数据会一直存活在Activity/Fragment中。因此ViewModel不能持有Context的对象,否则会出现内存泄露。

也就是说ViewModel一直保留在内存中,直到它的作用域永久消失:在activity的情况下,当它finishes时;而在fragment的情况下,当它被detached时。

②Activity在生命周期中可能会触发多次onCreate(),而ViewModel只会在第一次onCreate()时创建,然后直到最后Activity销毁。

 

ViewModel的应用:

屏幕旋转后,使用户操作数据仍然存在。

 

2.ViewModel的使用

①写一个类继承自ViewModel

class MyViewModel : ViewModel() {

    private var number:Int = 0

    fun getNumber(): Int {

        return number

    }

    fun setNumber() {

        number++

    }

    override fun onCleared() {

        super.onCleared()

        //viewModel销毁时调用,可以做一些释放资源的操作,防止内存泄露

    }

}

②使用自定义的ViewModel

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

        val myViewModel = ViewModelProvider( this).get(MyViewModel::class.java)

        btn_add.setOnClickListener {

            myViewModel.setNumber()

            tv_text.setText("" + myViewModel.getNumber())

        }

    }

}

点击Button可以使TextView上的数字一直增加,而且旋转屏幕时数据也会保持,不会丢失(如果不使用ViewModel,旋转屏幕时TextView上的数据会变为0)。

ViewModel是一个抽象类,只有一个onCleared()方法。当ViewModel不再被需要,即与之相关的Activity/Fragment被销毁时,该方法会被系统调用。因此可以在该方法中执行一些资源释放的相关操作,防止造成内存泄露。注意: 当屏幕旋转而导致的Activity重建,并不会调用该方法。

注意:

①如果Activity重新创建,它接收的ViewModel实例与第一个Activity创建的实例相同。

②当Activity完成(不能简单理解为destroy)时,框架会调用ViewModel的onCleared()方法,以便它可以

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值