Kotlin ViewModel

Kotlin ViewModel 全流程指南

ViewModel 的核心作用是以注重生命周期的方式存储和管理界面相关的数据。它最伟大的地方在于:当手机屏幕旋转(配置更改)导致 Activity 重建时,ViewModel 中的数据不会丢失。


大纲

  1. 添加依赖
  2. [创建 ViewModel 类](#创建 ViewModel 类)
  3. 在-activity-或-fragment-中初始化
  4. [ViewModel 的生命周期](#ViewModel 的生命周期)
  5. [核心准则 Best Practices](#核心准则 Best Practices)
  6. 总结

1. 添加依赖

在 build.gradle.kts (Module: app) 中添加 Lifecycle 库:

kotlin 复制代码
dependencies {
    val lifecycle_version = "2.8.0" // 请检查最新版本
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
    implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
    // 如果在 Activity/Fragment 中使用 'by viewModels()' 扩展
    implementation("androidx.activity:activity-ktx:1.9.0")
}

2. 创建 ViewModel 类

ViewModel 应该存放所有的 UI 数据逻辑。建议配合 StateFlow 或 LiveData 使用,以实现响应式编程。

kotlin 复制代码
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class MyViewModel : ViewModel() {

    // 使用 StateFlow 管理状态
    private val _counter = MutableStateFlow(0)
    val counter: StateFlow<Int> = _counter

    fun incrementCounter() {
        _counter.value += 1
    }
}

3. 在 Activity 或 Fragment 中初始化

⚠️ 千万不要直接通过 val vm = MyViewModel() 来实例化,否则它就失去了生命周期感知的特性。必须通过 ViewModelProvider 或 by viewModels() 委托。

3.1 在 Activity 中

kotlin 复制代码
class MainActivity : AppCompatActivity() {

    // 使用 ktx 扩展函数(推荐)
    private val viewModel: MyViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 观察数据变化(以 Flow 为例)
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.counter.collect { count ->
                    // 更新 UI,例如:textView.text = count.toString()
                }
            }
        }
    }
}

3.2 在 Fragment 中(共享 ViewModel)

如果你希望 Fragment 之间共享数据,可以使用 activityViewModels()。

kotlin 复制代码
class MyFragment : Fragment() {

    // 与宿主 Activity 共享同一个 ViewModel 实例
    private val sharedViewModel: MyViewModel by activityViewModels()
}

4. ViewModel 的生命周期

理解 ViewModel 的生命周期至关重要。它的存活时间比具体的 Activity 实例更长。

阶段 说明
创建 当 Activity 第一次启动时
存活 当 Activity 因为旋转屏幕而销毁并重新创建时,ViewModel 依然存在
销毁 只有当 Activity 真正彻底结束(调用 finish())或进程被杀掉时,ViewModel 才会调用 onCleared() 并销毁

5. 核心准则 (Best Practices)

5.1 禁止持有 Context

⚠️ 绝对不要在 ViewModel 中引用 Activity、Fragment 或 View(会导致内存泄漏)。

如果需要 Context,请继承 AndroidViewModel(application):

kotlin 复制代码
class MyAndroidViewModel(application: Application) : AndroidViewModel(application) {

    private val prefs = application.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)

    fun saveData(key: String, value: String) {
        prefs.edit().putString(key, value).apply()
    }
}

5.2 单向数据流

复制代码
UI 观察 ViewModel 的状态  →  UI 的操作调用 ViewModel 的方法
                                    ↓
                           不要在 UI 中直接修改 ViewModel 的变量

5.3 轻量化

  • ViewModel 只负责 逻辑和数据
  • ViewModel 不负责 处理复杂的 UI 动画或具体的框架调用

总结

你是正在做传统的 XML 布局开发,还是已经在使用 Jetpack Compose 了?(Compose 中 ViewModel 的注入方式略有不同)。

关键点 说明
依赖添加 lifecycle-viewmodel-ktx + activity-ktx
实例化方式 by viewModels() 或 ViewModelProvider,禁止 new MyViewModel()
数据管理 配合 StateFlow / LiveData 实现响应式
生命周期 跨配置变化存活,真正 finish 时销毁
最佳实践 不持有 Context,单向数据流,轻量化
相关推荐
拥小抱9 小时前
Compose 知识点
android
文章永久免费只为良心9 小时前
Web应用安全与防护_第三章_日志文件包含_从一道 CTFshow 题目讲透「日志投毒型 LFI → RCE」:原理、时序陷阱与全变种攻防手册
android·网络安全·渗透测试·漏洞危害·漏洞描述·日志投毒·红队指南
AIsoft_86899 小时前
学术讲座录音如何整理?录音APP可行吗
android·iphone
Goway_Hui11 小时前
【KMP for OpenHarmony】-- 在鸿蒙工程中使用 Apollo-Kotlin
华为·kotlin·harmonyos
Patrick在香港12 小时前
一个斜杠,把毫秒变成十几秒
android·数据库·python·性能优化·正则表达式·回溯·redos
海雅达手持终端PDA13 小时前
工业手持终端的“去手机化”演进:看海雅达如何以“同轴扫摄”终结工程妥协,重塑工业PDA新范式
android·物联网·智能手机·硬件工程·能源·制造·iot
释厄62313 小时前
AI 军备竞赛悖论——为 AI 卖游戏但 AI 需要游戏母场景
人工智能·游戏·kotlin
booboosui14 小时前
删掉一个住在本机的 agent:8 处要清,顺序不能反
android
hcgeng14 小时前
Android获取崩溃日志
android