6.1 KiB
6.1 KiB
实施总览
本文档是 TeamSpeak Android 客户端实施计划的主索引,将设计文档拆分为可执行的实施步骤。 依据:
docs/sdk-bridge-api.md、docs/UI架构设计.md、docs/流程/
〇、已完成工作
| 阶段 | 状态 | 说明 |
|---|---|---|
| Go 层能力封装 | ✅ 完成 | go/teamspeak/bridge.go 已封装全部 SDK 能力,gomobile 编译为 AAR |
| Bridge 层实现 | ✅ 完成 | TSBridge.kt 单例直接包装 gomobile 导出的 TSClient,提供 Kotlin 友好 API |
当前架构:
Go SDK (teamspeak-go) → gomobile → AAR → TSBridge.kt (应用层桥接,单例)
事件流:Go goroutine → JNI callback(Go goroutine 线程)→ TSBridge → ViewModel → StateFlow → UI
一、实施步骤索引
| 步骤 | 文档 | 主要内容 | 对应流程 | 依赖步骤 | 状态 |
|---|---|---|---|---|---|
| 01 | 项目基础设施 | 项目结构、构建系统、依赖配置 | — | — | ✅ |
| 02 | Bridge 层实现 | TSBridge → TsClient 桥接、事件监听 | — | 01 | ✅ |
| 03 | 服务器配置页 | 连接 UI、输入验证、最近连接 | 01 连接服务器 | 02 | ⬚ |
| 04 | 连接与首次同步 | 连接流程、Identity、首次同步 | 01 + 08① | 03 | ⬚ |
| 05 | 频道列表页 | 频道树渲染、成员列表、未读指示 | 02 浏览频道 | 04 | ⬚ |
| 06 | 频道切换 | 频道切换流程、密码弹窗、ClientMove | 03 切换频道 | 05 | ⬚ |
| 07 | 聊天页 | 消息列表、发送消息、消息归档 | 04 文本消息 | 06 | ⬚ |
| 08 | 语音通信 | PTT 按钮、Opus 编码、语音发送/接收 | 05 语音通信 | 06 | ⬚ |
| 09 | 断开连接 | 主动断开、被动断开、被踢处理 | 07 断开连接 | 08 | ⬚ |
| 10 | 状态同步进阶 | 增量同步、补偿同步、重连全量同步 | 08 状态同步 ②③⑥ | 09 | ⬚ |
| 11 | 卡片与全局交互 | 服务器详情卡、频道详情卡、语音卡、Poke | UI架构 三、四 | 10 | ⬚ |
| 12 | 主题与收尾 | 暗色主题、边缘情况、稳定性 | — | 11 | ⬚ |
| 13 | EventBus 架构 | TS 事件与渲染线程分离、事件合并/节流 | — | 02 | ⬚ |
二、实施原则
- 先跑通最小闭环:连接 → 同步 → 显示频道 → 切换频道 → 发消息 → 断开
- 每步可验证:每个步骤完成后应能在真机或模拟器上运行并验证核心功能
- Bridge 层已完成:Go ↔ Kotlin 通信已通过
TsClient封装,后续步骤直接调用 - 状态管理清晰:严格遵循流程文档中的状态树和事件依赖
- UI 后于逻辑:先确保数据流正确,再打磨 UI 细节
三、技术栈确认
| 层级 | 技术 | 说明 |
|---|---|---|
| 协议层 | Go + teamspeak-go | 编译为 AAR,通过 gomobile 绑定 |
| Kotlin 封装层 | TSBridge (单例) | 直接包装 gomobile TSClient,JSON 传递复杂数据 |
| 桥接层 | TSBridge (单例) | 直接包装 gomobile TSClient,JNI 回调转 EventBus 事件 |
| 事件总线 | EventBus (单例) | 事件收集、合并、节流,TS 线程与渲染线程分离 |
| UI 层 | Kotlin + Jetpack Compose | Material Design 3 主题 |
| 状态管理 | ViewModel + StateFlow | 单向数据流,通过 EventBus 接收 TS 事件 |
| 音频 | Opus 编解码 | Android MediaCodec 或第三方库 |
| 网络 | UDP (SDK) + TCP (文件传输) | SDK 内部处理 |
四、文件结构预期
android/app/src/main/java/com/tsmobile/app/
├── MainActivity.kt # 入口
├── TSBridge.kt # 应用层桥接(直接包装 gomobile TSClient)
├── EventBus.kt # 事件总线(TS 事件收集、合并、分发)
├── data/ # 数据模型
│ ├── Models.kt # 频道、成员、消息等数据类
│ └── Repository.kt # 状态仓库
├── voice/ # 语音服务
│ ├── VoiceService.kt # 音频管线(采集、编码、解码、播放)
│ ├── OpusEncoder.kt # Opus 编码器
│ └── OpusDecoder.kt # Opus 解码器
├── ui/
│ ├── theme/ # Material 3 主题
│ ├── components/ # 可复用组件
│ └── screens/
│ ├── ServerConfigScreen.kt
│ ├── ChannelListScreen.kt
│ └── ChatScreen.kt
└── viewmodel/
├── ServerViewModel.kt # 连接生命周期(监听 Connected/Disconnected/Kicked)
├── ChannelViewModel.kt # 频道列表(监听 ClientEnter/Leave/Moved,debounce 刷新)
├── ChatViewModel.kt # 消息归档(监听 TextMessage)
└── VoiceViewModel.kt # 语音控制(VoiceService 直接处理,不经 EventBus)
五、风险与注意事项
- gomobile 限制已解决:
TSBridge.kt直接包装 gomobile 导出的TSClient,通过 JSON 字符串传递复杂数据 - 线程安全:Go JNI 回调在 Go goroutine 线程上执行(非 Android 主线程),通过
EventBus.emit()统一投递,ViewModel 在Dispatchers.Main上消费事件 - 事件合并:高频成员变化事件(ClientEnter/Leave/Moved)通过 debounce 合并,避免事件风暴导致频繁 refreshClientList
- Opus 编解码:SDK 不内置,需应用层集成(
voice/OpusEncoder.kt、voice/OpusDecoder.kt) - 语音延迟敏感:VoiceData 不经过 EventBus,由 VoiceService 在 Dispatchers.IO 上直接处理
- 文件传输:本文档范围暂不实现(见流程 06 说明)
- Identity 管理:首次生成后需持久化存储
- TSBridge 是全局单例:同一时间只能有一个活跃连接