项目初始化:用 Android Studio 搭建 Compose 项目

嗯,这一章我们开始动真格的了。很多同学学离线优先架构,第一步就卡在环境搭建上——不是 Gradle 版本对不上,就是依赖冲突搞得头大。我个人习惯是:先让项目跑起来,再逐步填业务逻辑。所以今天咱们就专心搞定 Compose 项目的骨架。

3.1 创建新项目时的版本选择

打开 Android Studio,选 New Project -> Empty Activity。这里有个坑:千万别手快直接点 Finish。Android Studio 默认会用最新稳定版的 AGP(Android Gradle Plugin)和 Kotlin 版本,但这个组合有时候和 Compose BOM 不兼容。我去年有个项目就是被 AGP 8.2 和 Compose 1.5 的隐式依赖坑了一把——编译没问题,一运行就 Crash。

所以我的习惯是:先看一眼官方 Compose 版本兼容表,心里有数再动手。这里给你一张我常用的版本组合参考表:

组件推荐版本(2025 Q1)说明
AGP8.3.0太新可能有 bug,太老不支持 Compose 插件
Kotlin1.9.22必须和 Compose 编译器版本对应
Compose BOM2024.02.02看 BOM 版本就够了,它统一管所有 Compose 库
Compose Compiler1.5.10这个版本号必须和 Kotlin 版本精确匹配
Hilt2.50离线架构少不了依赖注入
Room2.6.1本地持久化核心库

创建项目时,我建议你选“Minimum SDK”为 Android 7.0(API 24),别图省事用 API 21,因为 Room 和后台工作在很多老机型上跑不动离线同步逻辑。

3.2 Gradle 配置:从 project 到 module

项目创建完成后,第一件事不是写代码,是打开根目录的 build.gradle.kts(现在都用 Kotlin DSL 了吧?别再用 Groovy 了,维护起来真的头疼)。

// 根目录 build.gradle.kts
plugins {
    id("com.android.application") version "8.3.0" apply false
    id("org.jetbrains.kotlin.android") version "1.9.22" apply false
    id("com.google.dagger.hilt.android") version "2.50" apply false
    id("com.google.devtools.ksp") version "1.9.22-1.0.17" apply false
}

然后打开 app/build.gradle.kts,这是重头戏。我一般会分成三块来配置:

  • Android 块:设置 compileSdk、minSdk、targetSdk,以及 compose 选项
  • 依赖块:用 BOM 统一版本,不手动写单个库版本
  • KSP 块:处理 Room annotation processor

来看看我实际项目里的一个最小化配置(可以直接 copy 过去改):

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.dagger.hilt.android")
    id("com.google.devtools.ksp")
}

android {
    namespace = "com.example.offlinefirst"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.offlinefirst"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }

    buildFeatures {
        compose = true
    }

    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.10"
    }

    kotlinOptions {
        jvmTarget = "17"
    }
}

dependencies {
    // Compose BOM —— 所有 Compose 库版本由它统一管理
    val composeBom = platform("androidx.compose:compose-bom:2024.02.02")
    implementation(composeBom)

    // Compose 核心
    implementation("androidx.compose.ui:ui")
    implementation("androidx.compose.ui:ui-graphics")
    implementation("androidx.compose.ui:ui-tooling-preview")
    implementation("androidx.compose.material3:material3")
    implementation("androidx.activity:activity-compose:1.8.2")

    // 调试工具(只有 debug 模式才打包)
    debugImplementation("androidx.compose.ui:ui-tooling")
    debugImplementation("androidx.compose.ui:ui-test-manifest")

    // 离线架构三大件
    implementation("androidx.room:room-runtime:2.6.1")
    implementation("androidx.room:room-ktx:2.6.1")
    ksp("androidx.room:room-compiler:2.6.1")  // 用 KSP 替代 kapt,快很多

    implementation("com.google.dagger:hilt-android:2.50")
    ksp("com.google.dagger:hilt-compiler:2.50")

    // 网络(离线优先也要有网络层)
    implementation("com.squareup.retrofit2:retrofit:2.9.0")
    implementation("com.squareup.retrofit2:converter-gson:2.9.0")

    // 协程
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
}

// 如果 Room schema 需要导出用于数据库迁移
ksp {
    arg("room.schemaLocation", "$projectDir/schemas")
}
⚠️ 踩坑记录: 我曾经过度自信地把 Compose Compiler 版本和 Kotlin 版本写错了一位,结果编译过去但运行时 UI 全部没法渲染,log 里只有一些莫名其妙的 "Missing method" 错误。排查了整整半天才发现是版本映射问题。所以请你务必对照 Compose Compiler 与 Kotlin 版本映射表,一个数字都不能错。

3.3 理解这些依赖在离线架构中的角色

你可能会问:就建个空项目,为什么要拉这么多依赖?其实每个库在离线优先架构里都有明确的分工。我画了一张图帮你理清关系:

离线优先架构项目依赖关系图 Compose UI (Material3) ViewModel + Hilt Repository (离线策略) Room (本地数据库) Retrofit (远程 API) 协程 + WorkManager (同步调度) 💡 箭头:依赖方向;虚线:调度触发的同步

看明白了吗?从上到下是典型的单向依赖:Compose → ViewModel → Repository → 数据源。而左右两侧的 Room 和 Retrofit 是平级的——离线策略的核心就是让 Repository 决定「优先读哪个、什么时候同步」。WorkManager 则负责在后台乖乖地把待同步数据推上服务器。

3.4 别忘了检查几个关键配置

🔧 三个必须手动确认的点:

  1. Kotlin 编译器版本:在 composeOptions 里写的 kotlinCompilerExtensionVersion 必须和根目录的 Kotlin 插件版本匹配。我一般都去 官方兼容性表 查完再写。
  2. KSP 替代 kapt:Room 2.6.0 开始推荐用 KSP,编译速度能快 2-3 倍。记得在 build.gradle.kts 里声明 id("com.google.devtools.ksp"),然后用 ksp() 而不是 kapt()。
  3. minSdk 别太低:如果设置成 21,Room 和 Hilt 虽然能工作,但 WorkManager 的延迟初始化在某些低版本上会出诡异问题。我踩过这个坑——最后不得不把 minSdk 提到 24 才解决问题。

💡 我的小技巧:配置完 Gradle 后,先 Sync 一下,然后立刻写一个空的 Compose 页面和一个空的 Room Entity,跑一次构建。如果 2 分钟内能编译通过,恭喜你,后续工作会顺利很多。如果报错,赶紧检查版本号——大部分问题都出在版本不匹配上。

3.5 最后一步:验证项目骨架

为了确保你刚才配置的环境真的能用,我建议你写一个最简单的 Compose 页面测试一下:

// MainActivity.kt
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                Text("离线优先架构实战 —— 项目启动成功")
            }
        }
    }
}

如果能在模拟器或者真机上看到这行文字,说明 Compose 环境完全 OK。接下来你就可以放心地往项目里塞 Room、Hilt、WorkManager 了。嗯,到这里项目初始化就算正式完成。你手里的空项目已经搭好了离线优先架构的「地基」——剩下的就是一层层往上盖楼了。