前言
在 Android 应用程序开发中,Jetpack 是一个广受欢迎的开发工具包,它提供了许多组件和库,用于简化 Android 应用程序的开发过程。其中一个核心组件是 ViewModel,它用于管理应用程序的 UI 相关数据,并帮助处理配置更改时的生命周期问题。本文将全面介绍 Jetpack 中的 ViewModel 的使用方法和最佳实践。
什么是 ViewModel?
ViewModel 是 Jetpack 中的一个组件,它旨在存储和管理与 UI 相关的数据。ViewModel 的设计思想是将 UI 层与业务逻辑分离,使得数据在配置更改(例如屏幕旋转)时仍然保持可用。ViewModel 独立于 UI 层的生命周期,并在配置更改时保留其状态,因此可以轻松地处理生命周期感知的数据。
ViewModel 通常与 LiveData 结合使用,后者是一个可观察的数据容器。LiveData 使数据在 ViewModel 和 UI 之间进行双向绑定成为可能,从而使数据的更新可以自动反映在 UI 上。
如何使用 ViewModel?
要在应用程序中使用 ViewModel,首先需要在项目的 build.gradle 文件中添加 ViewModel 库的依赖:
dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
}
接下来,在 Activity 或 Fragment 中创建 ViewModel 的实例。通常,最好将 ViewModel 与特定的 Activity 或 Fragment 关联起来,以便在配置更改时保持一致。可以使用 by viewModels()
函数来实现这一点:
class MyActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
// ...
}
在上面的代码中,MyViewModel
是自定义的 ViewModel 类,by viewModels()
函数将为该 Activity 提供与之关联的 ViewModel 实例。类似地,在 Fragment 中,可以使用 by viewModels()
函数来创建关联的 ViewModel 实例。
在 ViewModel 类中,可以使用 LiveData
来存储和暴露与 UI 相关的数据。通过将数据封装在 LiveData 中,可以确保数据的更新在配置更改时得到正确处理。下面是一个示例:
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> get() = _data
// ...
}
在上面的代码中,_data
是一个私有的 MutableLiveData 对象,data
是对其的公开访问。ViewModel 可以使用 _data.value
来更新数据,并通过 data
属性将数据暴露给 UI 层。
最后,在 Activity 或 Fragment 中,可以观察 ViewModel 中的 LiveData 来更新 UI。通常,可以使用 observe()
函数来实现这一点:
viewModel.data.observe(this, { newData ->
// 在此处更新 UI
})
在上面的代码中,this
表示当前的 Activity 或 Fragment,newData
是 ViewModel 中的数据更新时的参数。在观察者的回调中,可以根据新的数据更新 UI,以便及时反映 ViewModel 中的变化。
ViewModel 的生命周期
ViewModel 的生命周期与其关联的 Activity 或 Fragment 的生命周期不同。ViewModel 的生命周期可以跨越多个配置更改,而不受 Activity 或 Fragment 的销毁和重新创建的影响。这意味着 ViewModel 可以在配置更改后继续保留其状态,并且不会丢失数据。
ViewModel 的生命周期可以总结为以下几个阶段:
-
创建阶段:ViewModel 在 Activity 或 Fragment 首次创建时被实例化。可以在 ViewModel 的构造函数中进行初始化工作。
-
活跃阶段:ViewModel 在其关联的 Activity 或 Fragment 处于活跃状态时保持活跃。在这个阶段,可以观察 LiveData 或执行其他与 UI 相关的操作。
-
不活跃阶段:当 Activity 或 Fragment 进入非活跃状态(例如,另一个 Activity 位于前台)时,ViewModel 会进入不活跃阶段。在这个阶段,可以暂停一些资源消耗较大的操作,以避免浪费资源。
-
清理阶段:当 Activity 或 Fragment 被销毁时,ViewModel 将进入清理阶段。在这个阶段,可以释放资源、取消所有的观察者和清理任何不再需要的对象。
要了解 ViewModel 的当前生命周期状态,可以使用 ViewModel 的 onCleared()
方法来检测 ViewModel 是否已被清理。
最佳实践和注意事项
以下是使用 ViewModel 时的一些最佳实践和注意事项:
-
将 ViewModel 与 UI 层逻辑分离:ViewModel 应该专注于管理数据和业务逻辑,而不应包含与 UI 层直接相关的代码。将 UI 逻辑放在 Activity 或 Fragment 中,以便实现良好的分离和可测试性。
-
避免将 Activity 或 Fragment 作为参数传递给 ViewModel:ViewModel 应该是与特定 UI 组件无关的,因此避免将 Activity 或 Fragment 作为参数传递给 ViewModel。如果需要在 ViewModel 中执行某些操作(例如,导航到另一个屏幕),可以使用回调接口或 LiveData 来通知 UI 层。
-
使用 Lifecycle-Aware 组件:ViewModel 通常与 Lifecycle-Aware 组件(如 LiveData 和 LifecycleObserver)一起使用,以便更好地管理生命周期。这些组件能够自动感知生命周期变化,并在适当的时机处理数据的更新和资源的释放。
-
避免在 ViewModel 中持有对 Context 的引用:由于 ViewModel 的生命周期可能超出 Activity 或 Fragment 的生命周期,因此避免在 ViewModel 中持有对 Context 的引用,以避免内存泄漏。如果需要使用 Context,可以使用 Application Context 或传递特定的上下文参数。
-
单一职责原则:每个 ViewModel 应该专注于管理特定 UI 组件或屏幕的数据。避免将过多的责任放在单个 ViewModel 中,以保持代码的清晰性和可维护性。
-
使用 ViewModelFactory 进行依赖注入:如果 ViewModel 需要依赖其他对象或参数进行初始化,建议使用 ViewModelFactory 来创建 ViewModel 实例,并将所需的依赖项传递给 ViewModel。这样可以更好地进行依赖注入,并确保 ViewModel 的可测试性。
-
避免在 ViewModel 中进行耗时操作:ViewModel 应该专注于数据管理,而不应执行耗时的操作。如果需要执行耗时操作,例如从网络加载数据或进行数据库访问,建议将这些操作委托给其他组件(如 Repository)来处理。
-
使用适当的作用域管理 ViewModel:根据需要,可以使用不同的作用域来管理 ViewModel 的生命周期。例如,可以使用 Activity 作为 ViewModel 的作用域,以确保 ViewModel 与特定的 Activity 相关联,并在 Activity 被销毁时进行清理。
总结
Jetpack 中的 ViewModel 是一个强大的组件,可帮助简化 Android 应用程序的开发过程并解决配置更改时的生命周期问题。使用 ViewModel 可以实现 UI 与数据的分离,使得数据在配置更改后仍然可用,并且可以通过 LiveData 实现数据的双向绑定。
在使用 ViewModel 时,建议遵循最佳实践和注意事项,例如将 ViewModel 与 UI 逻辑分离、避免持有对 Context 的引用、使用 Lifecycle-Aware 组件等。通过正确使用 ViewModel,可以提高应用程序的可维护性、可测试性,并提供更好的用户体验。
最后
如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。
如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。
全套视频资料:
一、面试合集
二、源码解析合集
三、开源框架合集
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓