跳转到正文
YGJoon 技术博客

Android Kotlin Wear OS 与 Compose 多端协同

发布于:
·807 字 · 约 2 分钟·作者:
Wear OS 开发实战:手表端 Compose 布局差异、Tiles 快捷卡片、手机手表数据同步,以及低功耗场景下的取舍。
Android Kotlin Wear OS 与 Compose 多端协同文章封面
目录

开发环境

Gradle 配置:

dependencies {
    implementation("androidx.wear.compose:compose-foundation:1.3.0")
    implementation("androidx.wear.compose:compose-material:1.3.0")
    implementation("androidx.wear.tiles:tiles:1.3.0")
    implementation("androidx.wear.tiles:tiles-material:1.3.0")
}

Compose 布局差异

@Composable
fun WearHomeScreen() {
    Scaffold(
        timeText = { TimeText() },
        vignette = { Vignette(vignettePosition = VignettePosition.TopAndBottom) },
        positionIndicator = { PositionIndicator() }
    ) {
        ScalingLazyColumn {
            item { Text("心率", style = MaterialTheme.typography.titleMedium) }
            items(steps) { step -> Text(step.toString()) }
        }
    }
}

手机与手表协同

@Serializable
data class HealthSnapshot(val steps: Int, val heartRate: Int)

suspend fun sendSnapshot(client: MessageClient, nodeId: String, snapshot: HealthSnapshot) {
    val payload = Json.encodeToString(snapshot).encodeToByteArray()
    client.sendMessage(nodeId, "/health", payload)
}

手表端接收:

class WearMessageService : WearableListenerService() {
    override fun onMessageReceived(messageEvent: MessageEvent) {
        if (messageEvent.path == "/health") {
            val snapshot = Json.decodeFromString<HealthSnapshot>(String(messageEvent.data))
            scope.launch { repository.update(snapshot) }
        }
    }
}

Tiles 与 Complications

class StepsTileService : TileService() {
    override fun onTileRequest(requestParams: TileRequest): ListenableFuture<Tile> {
        val timeline = Timeline.Builder()
            .addTimelineEntry(TimelineEntry.Builder().setLayout(stepsLayout()).build())
            .build()
        return Futures.immediateFuture(Tile.Builder().setResourcesVersion("1").setTimeline(timeline).build())
    }
}

测试与调试

性能与功耗

常见问题

问题原因解决方案
数据延迟蓝牙或网络连接不稳定在发送前检测节点连接状态,增加重试
UI 截断圆形屏幕未处理安全区域使用 Modifier.fillMaxSize().padding(innerPadding)
编译依赖冲突Wear Compose 与手机 Compose 版本不一致对齐 Compose BOM 版本

实战案例:WearOS 是”手机 App 的遥控器”

WearOS 开发有个根本认知:手表不是小手机。它的交互是”瞥一眼”(glanceable)——抬腕 3 秒就要看完。所以 WearOS 的 UI 范式和手机完全不同:

和手机 App 的协同走 Data Layer API(DataClient/MessageClient),比如手机上下单、手表震动提醒。我在 Flutter 侧没做过 WearOS(Flutter 对 WearOS 的支持很弱,这是原生开发的护城河之一),但思路和蓝牙设备通信是一样的:短连接、少数据、省电第一。

Horologist(Google 官方的 WearOS 组件库)是起手标配,别自己造轮子。它的 MediaPlayer、Tile 模板都是按手表交互范式调好的。

一句话:WearOS 开发先忘掉手机那套,从”抬腕 3 秒”倒推设计。

参考:Android 官方文档《Wear OS》;Horologist GitHub(google/horologist)

总结

动手表端 Compose 需要适应圆形屏幕与功耗限制。通过 Data Layer API 实现手机与手表数据同步,结合 Tiles 提供一目了然的信息展示。合理规划同步频率与布局,可实现跨端一致体验。


分享这篇文章:


相关文章

上一篇
Android Kotlin Compose 动画进阶
下一篇
Android Kotlin App Startup 优化策略