Jetpack Compose 已成为 Android 官方推荐的 UI 工具包,但声明式范式下的状态管理和架构设计与传统 View 系统截然不同。本文基于实际项目经验,分享一套经过验证的 Compose 架构方案。

单向数据流(UDF)

Compose 的核心原则是 UI 是状态的函数:UI = f(state)。数据应单向流动:

事件向上传递(User Action → ViewModel),状态向下流动(ViewModel → Composable)
@Composable
fun UserScreen(viewModel: UserViewModel = hiltViewModel()) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    UserContent(
        state = uiState,
        onRefresh = viewModel::refresh,
        onUserClick = viewModel::selectUser
    )
}

UiState 密封类设计

用密封类(sealed class/interface)表达 UI 的所有可能状态,避免多个 Boolean 标志位:

sealed interface UserUiState {
    data object Loading : UserUiState
    data class Success(val users: List<User>) : UserUiState
    data class Error(val message: String) : UserUiState
}

Composable 中用 when 穷举所有分支,编译器会检查遗漏,杜绝「忘记处理 Loading 状态」的 bug。

状态提升与 Composable 职责

Composable 分为两类:

经验法则:默认写无状态 Composable,仅在状态不需要跨组件共享时才在内部持有。

导航:Navigation Compose

Navigation Compose 2.x 支持类型安全路由(Kotlin Serialization):

@Serializable data object HomeRoute
@Serializable data class DetailRoute(val id: String)

NavHost(navController, startDestination = HomeRoute) {
    composable<HomeRoute> { HomeScreen(onNavigate = { id ->
        navController.navigate(DetailRoute(id))
    }) }
    composable<DetailRoute> { backStackEntry ->
        val route = backStackEntry.toRoute<DetailRoute>()
        DetailScreen(id = route.id)
    }
}

模块化策略

中大型项目推荐按功能模块拆分 Gradle module:

  1. :core:ui — 主题、通用 Composable、扩展函数
  2. :core:data — Repository、数据源、网络层
  3. :feature:home — 首页的 ViewModel + Screen + Navigation
  4. :feature:detail — 详情页独立模块
  5. :app — 组装入口、Hilt 依赖注入图

性能注意事项

小结

Compose 架构的基石是单向数据流 + 密封类 UiState + 无状态 Composable。配合 Hilt 依赖注入和模块化拆分,可以构建出可测试、可维护的现代 Android 应用。