2. 项目工程化起点

Wear OS 项目与手机端 Android 项目最大的区别,不在于代码写法,而在于工程结构从一开始就要为“手表形态”服务。手表屏幕小、内存紧、电量敏感,且同一应用往往需要同时覆盖圆形与方形表盘、不同 DPI、不同 API 级别,甚至要区分“独立应用”和“依赖手机的应用”。因此,工程化起点的核心任务是:把模块边界、构建配置、依赖来源、设备适配和版本控制这五件事一次性定清楚,避免后期返工。

一、模块划分:app 与 wear 的职责边界

推荐采用“手机模块 + 手表模块 + 共享模块”的三段式结构。手机模块负责账号、支付、内容管理等重逻辑;手表模块只保留表盘交互、快捷操作、健康数据采集等轻量能力;共享模块存放数据模型、网络协议、常量与工具类。这样做的直接好处是:手表 APK 体积可控,且共享代码不会因为手机端引入重型库而被拖累。

典型目录结构如下:

MyWearApp/
├── app/                 # 手机端模块
├── wear/                # Wear OS 手表模块
├── shared/              # 共享 Kotlin 模块
├── build.gradle.kts     # 根构建脚本
├── settings.gradle.kts  # 模块声明
└── gradle/libs.versions.toml  # 版本目录

在 settings.gradle.kts 中显式声明三个模块,避免隐式包含导致构建范围失控:

include(":app", ":wear", ":shared")

二、Gradle 配置:用版本目录统一管理

Wear OS 项目依赖数量多、版本耦合强,建议使用 Gradle Version Catalog(libs.versions.toml)集中声明版本。这样升级 Compose、Wear Compose、Kotlin 时只需改一处,避免各模块版本漂移。

[versions]
kotlin = "1.9.24"
agp = "8.5.0"
composeBom = "2024.06.00"
wearCompose = "1.4.0"
coroutines = "1.8.1"

[libraries]
wear-compose = { module = "androidx.wear.compose:compose-material", version.ref = "wearCompose" }
wear-compose-foundation = { module = "androidx.wear.compose:compose-foundation", version.ref = "wearCompose" }
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

手表模块的 build.gradle.kts 关键配置如下,注意 minSdk 建议不低于 30(Wear OS 3 起点),targetSdk 跟随最新稳定版:

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

    defaultConfig {
        applicationId = "com.example.wear"
        minSdk = 30
        targetSdk = 34
        versionCode = 1
        versionName = "1.0.0"
    }

    buildFeatures { compose = true }
    composeOptions { kotlinCompilerExtensionVersion = "1.5.14" }
}

dependencies {
    implementation(platform(libs.compose.bom))
    implementation(libs.wear.compose)
    implementation(libs.wear.compose.foundation)
    implementation(libs.coroutines.android)
    implementation(project(":shared"))
}

三、依赖管理:手表端要“做减法”

手表模块的依赖策略与手机端相反:能不加就不加。常见误区是把手机端的 Retrofit、Room、图片加载库整套搬过来,结果 APK 膨胀、冷启动变慢。建议手表端只保留:Wear Compose、协程、轻量网络(如 OkHttp 或直接使用 HttpURLConnection)、以及必要时的 Data Layer API。数据持久化优先用 DataStore 或 SharedPreferences,而非 Room。

如果手表需要与手机通信,使用 play-services-wearable 的 MessageClient / DataClient,而不是自建 Socket。依赖声明示例:

implementation("com.google.android.gms:play-services-wearable:18.2.0")

四、多设备适配:圆形、方形与 DPI

Wear OS 设备形态差异大,适配要点有三:一是布局使用 Box + fillMaxSize 而非固定尺寸;二是通过 LocalConfiguration.current.isScreenRound 判断屏幕形状,圆形屏内容需内缩约 12% 避免被裁切;三是为不同 DPI 提供 drawable-hdpi、drawable-xhdpi 等资源目录。

下面这张图展示了从工程结构到设备适配的完整关系,帮助理解各层如何协同:

Wear OS 工程化结构:模块 · 构建 · 依赖 · 适配 模块层 app(手机端) 账号 · 支付 · 内容管理 wear(手表端) 表盘 · 快捷操作 · 健康采集 shared(共享) 数据模型 · 网络协议 · 工具类 依赖 依赖 构建层 Gradle Version Catalog(libs.versions.toml) 统一 Kotlin / AGP / Compose BOM / Wear Compose 版本,消除模块间版本漂移 依赖层 手表端依赖(做减法) Wear Compose · 协程 · OkHttp DataStore · play-services-wearable 共享模块依赖 Kotlin 标准库 · 序列化 · 网络协议 不引入 UI 框架,保持纯净 适配层 圆形屏 内容内缩 12% 方形屏 fillMaxSize 自适应 多 DPI 资源 hdpi / xhdpi / xxhdpi 版本控制 main 稳定发布 develop 日常集成 feature/* 功能开发 hotfix/* 紧急修复 tag: v1.0.0 tag: v1.1.0 tag: v1.1.1 .gitignore build/ · .gradle/ local.properties

五、版本控制策略

Wear OS 项目建议采用 main / develop / feature / hotfix 四类分支。关键原则是:libs.versions.toml 的版本变更必须走独立提交,便于回溯;local.properties、build/、.gradle/ 必须写入 .gitignore;每次发版打 tag(如 v1.0.0),tag 与 versionName 保持一致。

实操建议:首次搭建完成后,执行 ./gradlew :wear:assembleDebug 验证手表模块可独立构建;再执行 ./gradlew :app:assembleDebug 验证手机模块不受影响。若手表模块构建失败,优先检查 minSdk 是否低于 30、Wear Compose 版本是否与 Compose BOM 兼容。
常见坑:不要在 shared 模块中引入 Android UI 依赖,否则手表模块会被迫打包大量无用资源;wear 模块的 applicationId 必须与手机端不同,否则安装时会冲突。