首页 / Android 入门教程 / 应用架构指南

Android 入门教程

应用架构指南

本教程共 100 篇 · 第 77 篇 · 更新于 2026-07-28 · 约 8 分钟阅读

AndroidAndroid 入门教程架构MVVMRepositoryJetpack单向数据流

77. 应用架构指南

本节目标:理解官方推荐的 Android 应用架构,掌握分离关注点、单一可信来源、单向数据流三大原则,知道界面层、网域层、数据层各干什么,为后面写 ViewModel、MVVM 打基础。

前面学的 Activity、Compose、网络、存储都是单点能力。真正做应用,得先把架构搭好,不然代码越写越乱。这章讲官方推荐的应用架构。

为什么需要架构

打个比方,建房子。先把承重墙、水管、电线规划好,后面装修才顺手。要是直接堆砖头,装到一半发现厕所没通水管,推倒重来代价大。

应用也一样。Activity 里塞网络请求、数据库操作、UI 刷新、业务判断,看着能跑,但有几个问题:

  • 旋转屏幕数据没了。
  • 业务逻辑混在 UI 里,没法测试。
  • 网络层换库要改 Activity。
  • 多人开发冲突严重。

架构就是给应用分层、定边界,让每一部分职责清晰。

四大原则

1. 分离关注点(Separation of Concerns)

每层、每个类只干一件事。Activity 该管 UI 就别管数据;Repository 该管数据就别管 UI。

最常见的反例是「God Activity」:一个 Activity 几千行代码,UI、网络、数据库、业务逻辑全塞里面。改一处崩三处。

2. 数据模型驱动 UI

UI 是数据的视图,数据变了 UI 跟着变。不要让 UI 自己持有状态,状态应该来自数据层。

打个比方,UI 是镜子,数据是真人。镜子只负责照出真人的样子,真人变了镜子里的影像自然变。如果让镜子自己「想象」一个影像,和真人就脱节了。

3. 单一可信来源(Single Source of Truth,SSOT)

每种数据只有一个「权威来源」,其他地方都是它的副本。修改数据只能改 SSOT,其他地方订阅它的变化。

比如用户数据,SSOT 是数据库。ViewModel 从数据库读,UI 从 ViewModel 读。网络拉到新数据,先写数据库,数据库一变 ViewModel 自动收到,UI 自动更新。

4. 单向数据流(UDF)

数据从上往下流(SSOT -> UI),事件从下往上流(UI -> SSOT)。UI 不能直接改数据,只能发事件让 SSOT 改。

[数据层] -> [ViewModel] -> [UI]
   ↑                          |
   └-------- 事件 -------------┘

好处是数据流向清晰,调试好追,状态一致。

三层架构

官方推荐至少两层:界面层 + 数据层。复杂应用加一层网域层。

界面层(UI Layer)

负责在屏幕上显示数据。包含:

  • UI 元素:Compose 可组合函数,或者 View/XML。
  • 状态容器:通常是 ViewModel,持有 UI 状态,处理业务逻辑。

界面层不直接访问数据库或网络,它只观察 ViewModel 暴露的状态,并把用户事件传给 ViewModel。

class UserViewModel(private val repo: UserRepository) : ViewModel() {
    private val _uiState = MutableStateFlow<UserUiState>(Loading)
    val uiState = _uiState.asStateFlow()

    fun loadUser(id: String) {
        viewModelScope.launch {
            _uiState.value = Loading
            try {
                _uiState.value = Success(repo.getUser(id))
            } catch (e: Exception) {
                _uiState.value = Error(e)
            }
        }
    }
}

数据层(Data Layer)

包含业务逻辑和数据访问。由多个 Repository 组成,每个 Repository 管一类数据。

Repository 的职责:

  • 向上层暴露数据(通常是 Flow)。
  • 集中数据变化。
  • 解决多数据源冲突(比如网络 vs 本地数据库)。
  • 包含业务逻辑。

每个数据源类(DataSource)只管一个来源:网络、数据库、文件、缓存等。

class UserRepository(
    private val remote: UserRemoteDataSource,
    private val local: UserLocalDataSource
) {
    fun observeUser(id: String): Flow<User> = local.observeUser(id)

    suspend fun refreshUser(id: String) {
        val user = remote.fetchUser(id)
        local.saveUser(user)
    }
}
Tip

离线优先应用里,数据库是 SSOT。Repository 先把网络数据写库,UI 观察数据库 Flow,自动收到更新。这种模式叫「Single Source of Truth」。

网域层(Domain Layer)

可选层,介于界面层和数据层之间。封装复杂的业务逻辑,或者多个 ViewModel 共用的简单逻辑。

类叫「用例(UseCase)」或「交互方(Interactor)」。每个用例负责一项功能。

class GetTimeZoneUseCase(private val repo: SettingsRepository) {
    suspend operator fun invoke(): TimeZone {
        return repo.getTimeZone()
    }
}

什么时候用网域层:

  • 业务逻辑复杂,多个 ViewModel 共用。
  • 需要组合多个 Repository 的数据。
  • 团队约定要清晰分层。

简单应用可以不要这层,ViewModel 直接调 Repository。

推荐的现代架构

现代 Android 应用架构的特点:

  • 自适应分层:能适应手机、平板、折叠屏、车载。
  • 每层都用 UDF:状态单向流动。
  • 状态容器:ViewModel 管理复杂 UI 状态。
  • 协程和 Flow:异步和数据流的标准方案。
  • 依赖注入:Hilt 或者手动 DI,解耦依赖。

单 Activity 架构

早期 Android 一个屏幕一个 Activity,导致 Activity 之间数据传递复杂、返回栈难管理。现代架构推荐单 Activity + 多 Compose 目的地

  • 一个 Activity 作为容器。
  • 每个屏幕是一个 Composable,用 Navigation 组件管理跳转。
  • ViewModel 作用域到 Navigation 目的地,返回栈管理简单。
Note

单 Activity 不是强制,但官方主推。Fragment 时代也是单 Activity + 多 Fragment 的思路,现在 Compose 直接替代了 Fragment 的角色。

依赖管理

类之间会有依赖。比如 ViewModel 依赖 Repository,Repository 依赖 DataSource。两种模式管理:

  • 依赖注入(DI):类不自己 new 依赖,由外部提供。Hilt 是官方推荐的 DI 库。
  • 服务定位器:有个注册表,类去那里拿依赖。

DI 更易测试(测试时传 Mock)和解耦,是主流方案。下一章的 ViewModel 章节会演示,专门的依赖注入在第 97 章讲。

状态生命周期

状态容器(ViewModel)有自己的生命周期,跟它关联的 UI 元素绑定:

  • Activity 的 ViewModel:Activity finish 时清除。
  • Navigation 目的地的 ViewModel:目的地从返回栈移除时清除。
  • Composable 的 ViewModel:Composable 离开组合时清除。

ViewModel 在配置变化(如旋转屏幕)时不重建,这是它最大的价值。

最佳实践

官方建议:

  1. 不要把数据存到应用组件里。Activity、Service 会被系统随时销毁,存数据会丢。
  2. 减少对 Android 类的依赖。业务类别依赖 ContextResources,便于测试。
  3. 模块边界清晰。网络代码别散得到处都是,缓存和绑定别混在一个类。
  4. 少公开内部实现。模块对外只暴露必要 API。
  5. 专注核心业务。样板代码用 Jetpack 库处理。
  6. 配置变化保留状态。用 ViewModel。
  7. 可测试性。架构要让单元测试好写。

常见反模式

  1. God Activity:Activity 干所有事。拆成 ViewModel + Repository。
  2. 网络请求写在 UI 里:测试难、复用难。移到 Repository。
  3. Repository 返回 LiveData:LiveData 应该只在 ViewModel 和 UI 之间。Repository 用 Flow。
  4. 多个 SSOT:网络和数据库各存一份,不同步。统一以数据库为准。
  5. 业务逻辑散在 UI:换 UI 框架(View -> Compose)业务逻辑要重写。逻辑放 ViewModel 或者 UseCase。

小结

应用架构四大原则:分离关注点、数据驱动 UI、单一可信来源、单向数据流。三层结构:界面层(UI + ViewModel)、可选网域层(UseCase)、数据层(Repository + DataSource)。单 Activity + Compose 是现代主推,ViewModel 在配置变化时保留状态。

下一章讲 ViewModel 怎么写,把这层的职责说透。