1. LiveData与ViewModel初探:什么是LiveData?什么是ViewModel?为什么需要它们?MVVM架构简介。

各位同学好,我是你们的老朋友。今天咱们正式开始《Kotlin Android LiveData与ViewModel状态管理实战》的第一章。

说实话,每次带新人或者做技术分享时,我总会被问到同一个问题:「为什么现在的Android开发非要搞LiveData和ViewModel?以前用回调、用Handler不也挺好的吗?」

嗯,这个问题问得好。咱们今天就把这事儿彻底聊透。

1.1 一个让我头疼的真实场景

先说说我自己的经历。几年前我接手过一个项目,是个新闻阅读App。代码里充斥着大量的AsyncTask、Handler、还有各种回调嵌套。当时有个需求:用户在列表页点击新闻,进入详情页,然后从详情页返回时,列表页要自动刷新。

你猜怎么着?

因为Activity重建(比如屏幕旋转),列表页的数据全丢了。用户返回时看到的是空白页面。更糟的是,后台的异步任务还在跑,结果回调到了一个已经被销毁的Activity上——直接崩溃。

这种问题,说白了就是生命周期管理混乱数据与UI耦合太紧导致的。

那LiveData和ViewModel就是来解决这些问题的。

1.2 什么是LiveData?

LiveData,从名字就能看出来——它是「活着的」数据。

官方定义:LiveData是一个可观察的数据持有者类。它感知组件的生命周期。

我换个说法你更好理解:

LiveData就像是一个智能广播站。它手里攥着一份数据,然后它知道谁在听它广播。更重要的是,它知道每个听众当前是「活跃」还是「非活跃」状态。

  • 如果听众在前台(活跃状态),数据一变,立刻通知。
  • 如果听众在后台(非活跃状态),数据变了,先记着,等听众回到前台再通知。
  • 如果听众已经「死」了(比如Activity被销毁),自动取消订阅,绝不通知。

这就避免了那个让我头疼的问题——回调到已销毁的Activity。

核心特性:

  • 数据驱动UI:数据变了,UI自动更新
  • 生命周期感知:自动管理订阅,避免内存泄漏
  • 不会因为屏幕旋转而丢失数据(配合ViewModel)
  • 数据共享:多个Fragment可以观察同一个LiveData

来个最简单的代码示例:

// 创建一个LiveData,持有用户年龄数据
val userAge = MutableLiveData<Int>()

// 在Activity或Fragment中观察它
userAge.observe(this) { age ->
    // 当age变化时,自动更新UI
    textView.text = "年龄:$age"
}

// 更新数据,UI会自动刷新
userAge.value = 25

你看,就这么几行代码,就实现了数据变化自动更新UI。不用手动刷新,不用担心中间状态。

1.3 什么是ViewModel?

ViewModel,直译就是「视图模型」。它存在的意义很简单:帮Activity和Fragment扛住配置变更

你想想看,Activity在屏幕旋转时会被销毁重建。那它里面的数据呢?全没了。以前我们怎么处理?用onSaveInstanceState()存Bundle,但Bundle能存的数据类型有限,大对象根本存不了。

ViewModel就是来解决这个痛点的。

ViewModel的生命周期比Activity长。只要Activity没有真正finish,ViewModel就一直活着。屏幕旋转?ViewModel不受影响,数据完好无损。

我的个人习惯:把所有与UI相关的数据都放在ViewModel里。Activity和Fragment只负责展示和交互,不负责存数据。这样哪怕Activity被重建100次,数据依然在。

看个例子:

class UserViewModel : ViewModel() {
    // 用户数据,放在ViewModel里
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> get() = _user

    fun loadUser(userId: String) {
        // 模拟网络请求
        viewModelScope.launch {
            val result = api.fetchUser(userId)
            _user.value = result
        }
    }
}

// 在Activity中使用
class UserActivity : AppCompatActivity() {
    private val viewModel: UserViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 观察数据
        viewModel.user.observe(this) { user ->
            // 更新UI
            bindUI(user)
        }
        // 加载数据
        viewModel.loadUser("123")
    }
}

注意看,by viewModels()这个委托。它保证了ViewModel的实例在屏幕旋转前后是同一个对象。数据自然就不会丢了。

1.4 为什么需要它们?

说白了,就三个字:解耦、存活、安全

问题 传统方式 LiveData + ViewModel
屏幕旋转数据丢失 用Bundle保存,麻烦且有限 ViewModel自动存活,数据不丢
异步回调空指针 手动判空,容易遗漏 LiveData自动感知生命周期,安全
UI与业务逻辑耦合 Activity里写网络请求、数据库操作 ViewModel统一管理,Activity只负责UI
多个Fragment共享数据 用接口回调,代码繁琐 共享同一个ViewModel,简单直接

我在项目中遇到过最典型的一个案例:一个电商App的商品详情页,包含商品信息、评论、推荐三个Fragment。这三个Fragment都需要访问同一个商品ID和用户信息。

如果用传统方式,你得在Activity里维护这些数据,然后通过接口传给Fragment。一旦Activity重建,全乱套。

用ViewModel呢?直接让三个Fragment共享同一个ViewModel实例。数据统一管理,生命周期统一感知。代码量减少一半,稳定性提升一倍。

1.5 MVVM架构简介

LiveData和ViewModel,其实是MVVM架构在Android中的具体实现。

MVVM的全称是Model-View-ViewModel。它把代码分成三层:

  • Model:数据层。包括网络请求、数据库、文件IO等。说白了就是「数据从哪里来」。
  • View:视图层。就是Activity、Fragment、各种View。它只负责「怎么展示」和「用户点了哪里」。
  • ViewModel:视图模型层。它是View和Model之间的桥梁。负责从Model拿数据,加工处理,然后交给View展示。

这三层的关系,我画了张图,你一看就明白:

MVVM 架构核心流程图 View 层 Activity / Fragment 负责UI展示和用户交互 观察LiveData,更新UI ViewModel 层 持有LiveData 处理业务逻辑 生命周期感知,数据存活 Model 层 Repository / DataSource 网络请求、数据库操作 数据持久化 观察 订阅 调用 获取数据 返回数据 通知更新 数据流向说明 1. View 通过 ViewModel 暴露的 LiveData 进行观察(订阅) 2. ViewModel 从 Model 层获取数据,处理后更新 LiveData 3. LiveData 数据变化时,自动通知 View 更新 UI 4. 整个过程是单向数据流:View → ViewModel → Model → ViewModel → View

这张图你看懂了吗?数据是单向流动的。View只负责展示和触发事件,不直接操作数据。ViewModel负责处理逻辑和持有数据。Model只负责提供原始数据。

这样做的好处是什么?

  • 可测试性:ViewModel不依赖Android组件,可以纯单元测试。
  • 可维护性:每一层职责清晰,改UI不影响数据逻辑。
  • 可复用性:同一个ViewModel可以给多个View用。

注意:千万不要在ViewModel里持有Activity或View的引用。我曾经见过有人把Context传到ViewModel里,结果导致内存泄漏。ViewModel的生命周期比Activity长,持有Activity引用会导致Activity无法被回收。

正确的做法是:如果需要Context,使用AndroidViewModel(它持有Application级别的Context)。

1.6 一个小总结

好了,咱们今天聊了不少。

LiveData是那个「智能广播站」,自动感知生命周期,数据变了就通知UI。

ViewModel是那个「数据保险箱」,屏幕旋转也不丢数据,帮Activity扛住配置变更。

MVVM架构就是让这三层各司其职,代码清晰又好维护。

嗯,第一章的内容就到这里。记住我今天说的那个新闻App的教训——别让数据跟着Activity一起「死掉」。用LiveData和ViewModel,让你的数据「活」起来。

我的建议:从今天开始,写新功能时强制自己用ViewModel + LiveData。哪怕只是一个简单的计数器。用多了,你就知道它们有多香了。


公众号:蓝海资料掘金营,微信deep3321