Android Jetpack组件ViewModel基本使用和原理分析

本文详细介绍了Android Jetpack的ViewModel组件,包括其定义、特点、基础使用、作用域内的唯一实例验证,以及源码分析,揭示了ViewModel为何不会随Activity的屏幕旋转而销毁,同时探讨了其生命周期和内存管理机制。
摘要由CSDN通过智能技术生成

本文整体流程:首先要知道什么是 ViewModel,然后演示一个例子,来看看 ViewModel 是怎么使用的,接着提出问题为什么是这样的,最后读源码来解释原因!

1.什么是ViewModel

1.1.定义

ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。在对应的作用域内,保正只生产出对应的唯一实例,保证UI组件间的通信。

ViewModel 一般要配合 LiveData、DataBinding一起使用

1.2.特点

通过定义我们可以得出

  • ViewModel不会随着Activity的屏幕旋转而销毁;
  • 在对应的作用域内,保正只生产出对应的唯一实例,保证UI组件间的通信

重点说一下ViewModel和onSaveInstanceState的关系

  • 对于简单的数据,Activity 可以使用 onSaveInstanceState() 方法从 onCreate() 中的捆绑包恢复其数据,但此方法仅适合可以序列化再反序列化的少量数据,而不适合数量可能较大的数据,如用户列表或位图。

  • ViewModel存储大量数据,不用序列化与反序列化

  • onSaveInstanceState存储少量数据

  • 相辅相成,不是替代

  • 进程关闭是onSaveInstanceState的数据会保留,而ViewModel销毁

2.ViewModel的基础使用

这个例子,主要是在 打印 User 的信息,并且点击按钮的时候更新 User 的信息并打印

2.1首先看一下 UserViewModel这个文件
//UserViewModel.kt

//自定义 User 数据类
data class User(var userId: String = UUID.randomUUID().toString(), var userName: String)

class UserViewModel : ViewModel() {
   

    private val userBean = User(userName = "刀锋之影")
    // 私有的 user LiveData
    private val _user = MutableLiveData<User>().apply {
   
        value = userBean
    }
    // 对外暴露的,不可更改 value 值的LiveData
    var userLiveData: LiveData<User> = _user

    //更新 User 信息
    fun updateUser() {
   
        //重新给 _user 赋值
        _user.value = userBean.apply {
   
            userId = UUID.randomUUID().toString()
            userName = "更新后: userName = 泰隆"
        }
    }
}
  • 自定义 User 数据类
  • 继承ViewModel,初始化 User
  • 声明私有的 user LIveData 用来更新数据
  • 对外暴露的,不可更改 value 值的LiveData
  • updateUser() 更新 User 信息的方法
2.2.再看下ViewModelActivity的内容
class ViewModelActivity : AppCompatActivity() {
   

    //初始化 UserViewModel 通过 ViewModelProvider
    private val userViewModel by lazy {
    ViewModelProvider(this)[UserViewModel::class.java] }

    override fun onCreate(savedInstanceState: Bundle?) {
   
        super.onCreate(savedInstanceState)
        val button = Button(this)
        setContentView(button)
        
        //观察 User 数据,并打印
        userViewModel.userLiveData.observe(this, Observer {
    user ->
            "User = $user".log()
        })

        //点击按钮更新 User 信息
        button.setOnClickListener {
   
            userViewModel.updateUser()
        }
    }
}
  • 初始化 UserViewModel
  • 观察 User 数据,并打印结果
  • 点击按钮时,更新 User 信息
2.3.结果日志
//log 日志
User = User(userId=34c1a1a4-967e-439c-91e8-795b8c162997, userName=刀锋之影)
User = User(userId=a6d0f09c-9c01-412a-ab4f-44bef700d298, userName=更新后: userName = 泰隆)
2.4总结:

以上就是 ViewModel 的简单使用,是配合 LiveData 的,具体 LiveData 的使用以及与原理分析,请看这篇文章

Android Jetpack组件LiveData基本使用和原理分析

通过上文可以 ViewModel 的定义以及特点,可以知道 ViewModel在对应的作用域内,保正只生产出对应的唯一实例,保证UI组件间的通信

我们来验证一下这个特点,我再写个例子,证明一下这个特点

3.验证ViewModel在对应的作用域内,保正只生产出对应的唯一实例

3.1.ViewModelActivity2类

在ViewModelActivity2中通过supportFragmentManager添加两个 Fragment

class ViewModelActivity2 : AppCompatActivity() {
   
    override fun onCreate(savedInstanceState: Bundle?) {
   
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_view_model)
        supportFragmentManager.beginTransaction()
            .add(R.id.flContainer, FirstFragment())
            .add(R.id.flContainer, SecondFragment())
            .commit()
    }
}
3.2.两个 Fragment
class FirstFragment : Fragment() {
   
    private val TAG = javaClass.simpleName

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
   
        val userViewModel = ViewModelProvider(activity as ViewModelStoreOwner)[UserViewModel::class.java]
        "userViewModel = $userViewModel".logWithTag(TAG)
        return super.onCreateView(inflater, container, savedInstanceState)
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值