移动应用架构设计:MVVM实战(面向零基础初学者)

代码旅人
2025-06-18 08:33
阅读 498

开篇:为什么我们需要MVVM架构?

开篇:为什么我们需要MVVM架构?

想象一下你正在做一道蛋糕。如果你把面粉、鸡蛋、糖都一股脑儿倒进搅拌机,最后可能很难做出理想的成品。但在烹饪中,如果按照“步骤清晰的菜谱”一步步操作——比如先打蛋、再加粉、最后烘烤,成功率就会大大提升。

开发移动应用也是一样!随着应用变得越来越复杂,我们不能随便写代码了事。需要一种清晰的组织结构,让代码更容易理解、维护和测试。

今天我们要讲的是一个在Android开发中非常流行的架构模式 —— MVVM(Model-View-ViewModel)

MVVM 是什么?用来做什么?

MVVM 是一种将界面逻辑与业务逻辑分离的设计模式:

  • View(视图):就是用户能看到的部分,比如按钮、文本框。
  • ViewModel:负责处理数据和逻辑,并将结果返回给 View 显示。
  • Model:负责处理真实的数据,比如从网络获取或从数据库读取。

简单来说,MVVM 就是把“蛋糕制作过程”分得清清楚楚,让你更轻松地应对复杂的项目!


环境准备:搭建你的开发环境

环境准备:搭建你的开发环境

工欲善其事,必先利其器。要学习 MVVM,你需要以下工具:

所需软件:

  1. Android Studio(推荐使用最新稳定版)
  2. JDK 11 或以上版本
  3. (可选)Android 设备模拟器或真机

安装步骤:

步骤1:下载安装 Android Studio

访问官网 https://developer.android.com/studio 下载适合你系统的安装包,然后一步步安装即可。

步骤2:启动 Android Studio 并配置 SDK

  • 启动后选择 "Start a new Android Studio project"
  • 选择模板 "Empty Activity"
  • 设置项目名称(例如 MyMvvmApp
  • 编程语言选择 Kotlin
  • 最低支持 Android 版本建议设置为 API 24 (Nougat) 或更高
  • 点击 Finish 创建项目

✅ 完成以上步骤后,你就拥有了一个可以运行的基础Android工程啦!


核心概念:用最通俗的语言解释专业术语

核心概念:用最通俗的语言解释专业术语

接下来我们会逐步讲解 MVVM 的三个组成部分,并配合代码示例说明它们之间的关系。

1. Model 层:你是谁?从哪来?

Model 是数据的来源。它不关心 UI,只负责提供数据。

举个例子:你做一个天气 App,Model 负责从服务器获取天气信息,或者从本地缓存拿。

示例:一个简单的数据类

data class User(val name: String, val age: Int)

这个类只是一个数据容器,没有涉及任何显示相关的内容。

再看一个带请求的例子:

假设你要从网络获取用户信息:

class UserRepository {
    fun getUser(): User {
        // 这里通常是网络请求,这里简化为直接构造一个User对象
        return User("张三", 25)
    }
}

这就是你的模型层,它专注于数据处理。


2. ViewModel 层:你告诉我该显示啥?

ViewModel 是 MVVM 中的核心部分,它是连接 View 和 Model 的桥梁。它负责:

  • 拿到 Model 的数据并处理
  • 把处理好的数据传给 View(如 Activity / Fragment)
  • 不持有 View 引用,避免内存泄漏

示例:创建 ViewModel 来获取用户数据

首先添加依赖:

dependencies {
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"
}

编写 ViewModel 类:

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class UserViewModel : ViewModel() {

    private val repository = UserRepository()

    private val _user = MutableStateFlow<User?>(null)
    val user: StateFlow<User?> = _user

    fun loadUser() {
        viewModelScope.launch {
            val fetchedUser = repository.getUser()
            _user.value = fetchedUser
        }
    }
}

在这个 ViewModel 中:

  • _user 是私有状态流,用于保存用户数据
  • user 是暴露出去的状态流,供 View 观察变化
  • loadUser() 方法调用了 Model 获取数据

3. View 层:我该怎么显示?

View 负责接收用户的输入,并根据 ViewModel 提供的数据更新界面。

在 Android 中,View 通常是 ActivityFragment

示例:绑定 View 和 ViewModel

首先添加 ViewModel 的依赖:

implementation "androidx.activity:activity-ktx:1.7.0"

接着修改你的 MainActivity.kt

import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private val userViewModel: UserViewModel by viewModels()

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

        userViewModel.user.observe(this, Observer { user ->
            if (user != null) {
                textViewName.text = "姓名:${user.name}"
                textViewAge.text = "年龄:${user.age}"
            }
        })

        buttonLoad.setOnClickListener {
            userViewModel.loadUser()
        }
    }
}

对应的布局文件 activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <Button
        android:id="@+id/buttonLoad"
        android:text="加载用户"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/textViewName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/textViewAge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

在这个 View 中:

  • 当用户点击按钮时调用 loadUser
  • 使用 observe 监听 ViewModel 的数据变化,自动更新页面内容

实战项目:写一个“每日一句”的小应用

实战项目:写一个“每日一句”的小应用

现在我们来做个小项目练手吧!目标是通过 MVVM 架构实现一个“每天显示一句励志名言”的 App。

第一步:定义 Model

新建一个数据类和仓库类:

// Quote.kt
data class Quote(val text: String, val author: String)
// QuoteRepository.kt
class QuoteRepository {
    fun getQuoteOfTheDay(): Quote {
        return Quote("成功不是将来才有的,而是从决定去做的那一刻起持续累积而成。", "俞敏洪")
    }
}

第二步:创建 ViewModel

class QuoteViewModel : ViewModel() {
    private val repository = QuoteRepository()
    private val _quote = MutableLiveData<Quote>()
    val quote: LiveData<Quote> = _quote

    fun loadQuote() {
        val quote = repository.getQuoteOfTheDay()
        _quote.value = quote
    }
}

第三步:编写 View(MainActivity)

class MainActivity : AppCompatActivity() {

    private val quoteViewModel: QuoteViewModel by viewModels()

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

        quoteViewModel.quote.observe(this, Observer { quote ->
            textViewQuote.text = "\"${quote.text}\"\n—— ${quote.author}"
        })

        buttonNext.setOnClickListener {
            quoteViewModel.loadQuote()
        }
    }
}

布局文件 activity_main.xml:

<LinearLayout ... >

    <TextView
        android:id="@+id/textViewQuote"
        android:textSize="20sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="请加载今日名言" />

    <Button
        android:id="@+id/buttonNext"
        android:text="显示下一句"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"/>

</LinearLayout>

🎉 成功!运行应用看看效果吧~点击按钮会更换名言。


常见问题解答(FAQ)

❓ 我为什么要用 MVVM?不用也可以?

你可以不用,但使用 MVVM 有助于提高项目的可维护性。当你一个人写小项目时,确实没什么差别,但项目越大越复杂,这种结构的优势就越明显。

❓ ViewModel 和普通的类有什么区别?

ViewModel 是专为 Android 设计的生命周期感知类,它可以安全地保留数据,即使屏幕旋转也不会丢失数据。

❓ 数据变了怎么通知 View 更新?

在 ViewModel 中使用 LiveDataStateFlow,它们可以被观察,当数据改变时,自动通知 UI 更新。

❓ 总是忘记导入某些库怎么办?

记得在 build.gradle 文件中添加相应依赖。如果不确定,可以尝试搜索官方文档或者查看 IDE 提示的错误信息。


学习建议:下一步怎么学?

恭喜你完成了第一个 MVVM 项目!接下来你可以沿着这些方向继续深入:

✅ 推荐学习路径:

  1. 学习 Kotlin 协程(Coroutines):异步任务的首选方式
  2. 了解 Room 数据库:学习如何持久化本地数据
  3. 掌握 Retrofit + MVVM:联网获取实时数据
  4. 引入 Jetpack Compose:现代化 UI 开发方式
  5. 阅读官方文档 & 参考优秀开源项目(如 Github 上的 “sunflower”)

📚 推荐资料:


总结

在本文中,我们以零基础的角度详细介绍了 MVVM 架构的概念、实践方法以及常见问题。通过一个简单的“每日一句”项目帮助你快速上手。

记住一句话:架构不是万能的,但它能让复杂的代码变得更清晰!

保持好奇心,多动手、多练习,你一定能成为一名优秀的移动开发者!

🔚 欢迎点赞、分享和继续关注我的系列教程!我们下次再见!👋

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝