# ts-mobile-go 构建指南(新手向) 本文档面向没有 Android 开发经验的同学,手把手教你从零把这个项目跑起来。 --- ## 目录 1. [项目是什么](#1-项目是什么) 2. [需要安装哪些软件](#2-需要安装哪些软件) 3. [安装步骤详解](#3-安装步骤详解) 4. [第一次构建(全流程)](#4-第一次构建全流程) 5. [在 IDEA 中打开和运行](#5-在-idea-中打开和运行) 6. [日常开发流程](#6-日常开发流程) 7. [常见问题排查](#7-常见问题排查) --- ## 1. 项目是什么 这是一个 TeamSpeak 客户端的 Android 手机应用,架构分两层: ``` ┌─────────────────────────────────────────────┐ │ Android 层(Kotlin + Jetpack Compose) │ │ 负责:界面显示、用户交互、状态管理 │ ├─────────────────────────────────────────────┤ │ Go 层(gomobile 编译成 .aar 库) │ │ 负责:TeamSpeak 协议通信、加密、数据处理 │ └─────────────────────────────────────────────┘ ``` **关键概念:** - **Go** — 一门编程语言,这里用来写 TeamSpeak 的底层通信逻辑 - **gomobile** — Go 官方工具,能把 Go 代码编译成 Android 能用的库文件(`.aar`) - **AAR** — Android Archive,Android 的库文件格式,类似于 Windows 的 `.dll` - **Gradle** — Android 的构建工具,类似前端的 Webpack/Vite,负责编译、打包、生成 APK - **APK** — Android Package,安卓手机上安装的应用文件,类似 Windows 的 `.exe` - **Kotlin** — Android 官方推荐的编程语言(类似 Java,但更现代) - **Jetpack Compose** — Android 的现代 UI 框架(类似 React/Vue,用代码写界面) --- ## 2. 需要安装哪些软件 | 软件 | 用途 | 必须? | |---|---|---| | **Go 1.26+** | 编译 Go 通信层代码 | ✅ 是 | | **IntelliJ IDEA** 或 **Android Studio** | 打开项目、编写代码、运行应用 | ✅ 是 | | **Android SDK** | Android 开发工具包(IDEA/Android Studio 会自带) | ✅ 是 | | **JDK 17+** | Java 运行环境,Gradle 构建需要 | ✅ 是 | | **ADB** | 把 APK 安装到手机上(IDEA 自带) | 手机调试需要 | **你大概率已经有了:** 如果你电脑上已经装过 IntelliJ IDEA 或 Android Studio,JDK 和 Android SDK 应该已经自带了,只需要额外装一个 Go。 --- ## 3. 安装步骤详解 ### 3.1 安装 Go 1. 打开 https://go.dev/dl/ 2. 下载 Windows 的 `.msi` 安装包(选 `go1.26.x.windows-amd64.msi`) 3. 双击安装,全部默认下一步即可 4. 安装完成后,**关闭并重新打开** 命令行(CMD 或 PowerShell),验证: ```bash go version # 应该输出类似:go version go1.26.0 windows/amd64 ``` ### 3.2 安装 gomobile gomobile 是 Go 的官方工具,用来把 Go 代码编译成 Android 能用的 `.aar` 文件。 打开命令行(CMD 或 PowerShell),执行: ```bash # 1. 安装 gomobile go install golang.org/x/mobile/cmd/gomobile@latest # 2. 初始化 gomobile(下载 Android 相关的工具链) gomobile init ``` 验证: ```bash gomobile version # 应该输出版本号,没有报错就说明成功了 ``` > **如果 `gomobile` 命令找不到:** 说明 Go 的 `bin` 目录没加到系统 PATH。 > 默认路径是 `C:\Users\你的用户名\go\bin`,把它加到系统环境变量 PATH 里, > 然后重新打开命令行。 ### 3.3 安装 IntelliJ IDEA 或 Android Studio 二选一: - **IntelliJ IDEA**(推荐,你可能已经有了)— 需要 Ultimate 版或安装 Android 插件 - **Android Studio**(免费)— https://developer.android.com/studio 安装时确保勾选了以下组件: - ✅ Android SDK - ✅ Android SDK Platform(API 26 以上) - ✅ Android SDK Build-Tools - ✅ JDK 17+(通常会自动安装) 安装完成后,确认 Android SDK 路径: - **IDEA**: File → Settings → Languages & Frameworks → Android SDK - **Android Studio**: 自动配置 记下这个路径(类似 `C:\Users\你的用户名\AppData\Local\Android\Sdk`),后面可能用到。 ### 3.4 设置环境变量 打开系统环境变量设置(Win + S 搜索"环境变量"): | 变量名 | 值 | 说明 | |---|---|---| | `ANDROID_HOME` | `C:\Users\你的用户名\AppData\Local\Android\Sdk` | Android SDK 路径 | | `JAVA_HOME` | `C:\Program Files\JetBrains\IntelliJ IDEA xxx\jbr` | JDK 路径(IDEA 自带的 JBR 即可) | > **怎么找到 JAVA_HOME?** > 如果你用的是 IntelliJ IDEA,它自带了一个 JDK(叫 JBR)。 > 路径类似:`C:\Program Files\JetBrains\IntelliJ IDEA 2024.3\jbr` > 在 IDEA 的 File → Project Structure → SDK 里可以看到具体路径。 把以下路径加到系统 `PATH` 变量中: ``` %ANDROID_HOME%\platform-tools %ANDROID_HOME%\tools ``` --- ## 4. 第一次构建(全流程) ### 4.1 理解构建流程 整个构建分两步: ``` 第一步:Go 代码 → .aar 文件 go/teamspeak/bridge.go ──(gomobile编译)──> android/app/libs/teamspeak.aar 第二步:Android 代码 + .aar → .apk 文件 android/app/src/**/*.kt + teamspeak.aar ──(Gradle构建)──> app-debug.apk ``` **必须先完成第一步,才能做第二步。** 因为 Android 代码依赖 Go 编译出来的 `.aar` 文件。 ### 4.2 一键构建(推荐) 项目根目录下有一个构建脚本,自动完成所有步骤: **Windows:** ```bash cd E:\MyProject\ts-mobile\ts-mobile-go build.bat ``` **Linux / macOS:** ```bash cd /path/to/ts-mobile-go chmod +x build.sh ./build.sh ``` 脚本会自动: 1. ✅ 检查 Go、gomobile、Android SDK 是否已安装 2. ✅ 下载 Go 依赖 3. ✅ 编译 Go 代码为 `.aar` 文件 4. ✅ 调用 Gradle 构建 APK 构建成功后,APK 文件在: ``` android/app/build/outputs/apk/debug/app-debug.apk ``` ### 4.3 手动构建(了解原理) 如果你想了解每一步在做什么,可以手动执行: **第一步:编译 Go → AAR** ```bash # 进入 Go 目录 cd E:\MyProject\ts-mobile\ts-mobile-go\go # 下载 Go 依赖(类似 npm install) go mod tidy # 编译为 AAR(这是关键命令) set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 gomobile bind -target=android -androidapi=26 -ldflags="-linkmode=external -extldflags=-Wl,--hash-style=both" -o ../android/app/libs/teamspeak.aar ./teamspeak ``` 命令解释: - `gomobile bind` — 把 Go 代码编译成 Android 库 - `-target=android` — 目标平台是 Android(自动包含所有架构:arm64、arm、x86、x86_64) - `-androidapi=26` — 最低支持 Android 8.0(API 26) - `-ldflags="-linkmode=external -extldflags=-Wl,--hash-style=both"` — **重要!** 两个关键标志: - `-linkmode=external` — 使用外部链接器(NDK 的 clang),避免 Go 内置链接器与 Android 信号处理冲突导致 SIGSEGV 崩溃 - `-extldflags=-Wl,--hash-style=both` — 强制生成兼容 Android 的 ELF hash 格式 - `-o ../android/app/libs/teamspeak.aar` — 输出文件路径 - `./teamspeak` — 要编译的 Go 包路径 > **为什么要设置 `JAVA_TOOL_OPTIONS`?** > gomobile 内部会调用 `javac`(Java 编译器)来生成 Java 接口代码。 > Windows 下 javac 默认用 GBK 编码,但我们的 Go 源码注释里有中文,是 UTF-8 编码。 > 不设置这个会导致编译报错"非法字符"。 **第二步:构建 Android APK** ```bash # 进入 Android 目录 cd E:\MyProject\ts-mobile\ts-mobile-go\android # 构建 debug 版本的 APK gradlew.bat assembleDebug ``` 构建成功后,APK 在 `app\build\outputs\apk\debug\app-debug.apk`。 ### 4.4 安装到手机 #### 方法 A:用 ADB 命令安装 1. 手机开启 **USB 调试**: - 进入手机 **设置 → 关于手机** - 连续点击 **版本号** 7 次,会提示"你已进入开发者模式" - 返回设置,进入 **开发者选项** - 打开 **USB 调试** 2. 用 USB 数据线连接手机到电脑 3. 手机上弹出"允许 USB 调试"的提示,点 **允许** 4. 在命令行执行: ```bash # 查看是否识别到手机 adb devices # 应该显示类似: # List of devices attached # XXXXXXXX device # 安装 APK adb install E:\MyProject\ts-mobile\ts-mobile-go\android\app\build\outputs\apk\debug\app-debug.apk ``` 5. 安装成功后,手机上找到 "ts-mobile-go" 应用,点击打开即可 #### 方法 B:直接把 APK 传到手机 1. 构建完成后,找到 `app-debug.apk` 文件 2. 通过微信/QQ/邮件/数据线 发送到手机 3. 手机上点击 APK 文件,允许安装未知来源应用,完成安装 --- ## 5. 在 IDEA 中打开和运行 ### 5.1 打开项目 1. 启动 IntelliJ IDEA 2. **File → Open** 3. 选择 `E:\MyProject\ts-mobile\ts-mobile-go\android\` 目录(注意是 `android` 子目录,不是根目录) 4. 弹出提示框,点击 **Trust Project** 5. 等待右下角进度条走完(Gradle Sync,首次可能需要 2-5 分钟下载依赖) > **如果提示安装 Android 插件:** 点击安装,然后重启 IDEA。 ### 5.2 配置运行设备 #### 使用模拟器(推荐新手) 1. 在 IDEA 中:**Tools → Device Manager**(或工具栏上的手机图标) 2. 点击 **Create Virtual Device** 3. 选择一个手机型号(比如 Pixel 7),点 Next 4. 选择系统镜像:选 **API 34** 或更高版本(需要先点击 Download 下载) 5. 点 Next → Finish 6. 在 Device Manager 中点击 ▶ 启动模拟器 #### 使用真机 1. 手机开启 USB 调试(见 4.4 节) 2. USB 连接电脑 3. IDEA 工具栏的设备下拉框中应该能看到你的手机 ### 5.3 运行应用 1. 确保 IDEA 工具栏的设备下拉框中选择了你的手机或模拟器 2. 确保运行配置选择的是 **app** 3. 点击绿色三角 **▶** 按钮(或按 `Shift + F10`) 4. IDEA 会自动编译并安装到设备上 > **注意:** 首次运行前,必须先完成 Go → AAR 的编译(第 4.2 或 4.3 节)。 > IDEA 只负责 Android 部分的构建,不会自动编译 Go 代码。 ### 5.4 查看运行日志 在 IDEA 底部面板找到 **Logcat** 标签页,可以看到应用的运行日志,方便调试。 --- ## 6. 日常开发流程 ### 改了 Go 代码(`go/` 目录下的文件) ```bash # 重新编译 AAR cd E:\MyProject\ts-mobile\ts-mobile-go\go set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 gomobile bind -target=android -androidapi=26 -ldflags="-linkmode=external -extldflags=-Wl,--hash-style=both" -o ../android/app/libs/teamspeak.aar ./teamspeak ``` 然后在 IDEA 中重新运行应用(点 ▶)即可。IDEA 会自动检测到 `.aar` 文件变化并重新打包。 ### 改了 Kotlin 代码(`android/` 目录下的文件) 直接在 IDEA 中点 ▶ 运行,IDEA 会自动增量编译。 ### 常用 IDEA 快捷键 | 操作 | 快捷键 | |---|---| | 运行 | `Shift + F10` | | 调试 | `Shift + F9` | | 全局搜索 | `Shift + Shift` | | 格式化代码 | `Ctrl + Alt + L` | | 查看当前文件结构 | `Ctrl + F12` | --- ## 7. 常见问题排查 ### Q: Gradle Sync 失败,提示 "Unresolved reference: dependencyResolutionManagement" **原因:** `settings.gradle.kts` 中的 API 名称写错了。 **解决:** 确认 `android/settings.gradle.kts` 第 9 行是: ```kotlin dependencyResolutionManagement { // ← 不是 dependencyResolution ``` ### Q: gomobile bind 报错 "missing golang.org/x/mobile dependency" **原因:** Go 模块缺少 `golang.org/x/mobile` 依赖。 **解决:** ```bash cd E:\MyProject\ts-mobile\ts-mobile-go\go go get -tool golang.org/x/mobile/cmd/gobind go mod tidy ``` ### Q: gomobile bind 报错 "unknown revision v0.0.0" **原因:** `go.mod` 中的依赖版本号不存在。 **解决:** 确认 `go/go.mod` 中的版本号是有效的: ``` require github.com/honeybbq/teamspeak-go v0.2.0 ``` 而不是 `v0.0.0`。 ### Q: javac 报错 "非法字符" 或 "GBK 不可映射字符" **原因:** Go 源码中的中文注释在 Windows 下被 javac 当作 GBK 编码处理。 **解决:** 在执行 gomobile 之前设置环境变量: ```bash set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 ``` ### Q: gomobile bind 报错 "math.MaxUint32 overflows int" **原因:** 上游 `teamspeak-go` 库在 32 位目标平台上有整数溢出问题。 **解决:** 这个问题已经通过本地 patch 修复了(见 `go/_patches/` 目录)。如果仍然遇到,可以只编译 64 位版本: ```bash gomobile bind -target=android/arm64 ... ``` 注意是 `android/arm64`,不是 `android`(后者会同时编译 32 位和 64 位)。 ### Q: adb devices 显示 "unauthorized" **原因:** 手机上没有授权这台电脑的 USB 调试。 **解决:** 检查手机屏幕,应该有一个"允许 USB 调试"的弹窗,点击允许。如果没有弹窗,拔掉 USB 重新插入。 ### Q: 安装 APK 时提示 "安装包似乎已损坏" **原因:** 可能是构建过程中出了问题,或者手机架构不匹配。 **解决:** 1. 在 IDEA 中执行 **Build → Clean Project**,然后重新构建 2. 确认手机是 64 位 ARM 架构(2018 年以后的手机基本都是) ### Q: IDEA 提示 "SDK not found" 或 "JAVA_HOME not set" **解决:** 1. **File → Project Structure → SDKs**,添加 Android SDK 路径 2. **File → Project Structure → Project**,设置 JDK 为 17 或更高 3. 确认系统环境变量中 `ANDROID_HOME` 和 `JAVA_HOME` 已正确设置 ### Q: 应用安装后打开闪退,Logcat 显示 "dlopen failed: empty/missing DT_HASH/DT_GNU_HASH" **原因:** Go 1.24+ 编译器生成的 .so 文件使用了 Android 链接器不认识的新 hash 格式(`DT_SUNW_HASH`)。Android 需要传统的 `DT_HASH` 或 `DT_GNU_HASH` 格式。 **解决:** 重新编译 AAR 时加上 `-ldflags` 标志(构建脚本已包含): ```bash cd E:\MyProject\ts-mobile\ts-mobile-go\go set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 gomobile bind -target=android -androidapi=26 -ldflags="-linkmode=external -extldflags=-Wl,--hash-style=both" -o ../android/app/libs/teamspeak.aar ./teamspeak ``` 然后重新构建 APK 并安装。 ### Q: 应用启动后几秒闪退,Logcat 显示 "Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)" **原因:** Go 运行时的信号处理与 Android 内存保护机制冲突。Go 使用 SIGSEGV 做垃圾回收和协程调度,但 Android 的 SEGV_ACCERR 策略会阻止这种用法。 **解决:** 重新编译 AAR 时加上 `-linkmode=external` 标志(构建脚本已包含): ```bash gomobile bind ... -ldflags="-linkmode=external -extldflags=-Wl,--hash-style=both" ... ``` `-linkmode=external` 强制 Go 使用 NDK 的外部链接器,避免内置链接器的信号处理冲突。 ### Q: 应用安装后打开闪退(其他原因) **可能原因:** Go 编译的 `.aar` 文件有问题,或者没有 `.aar` 文件。 **排查:** 1. 确认 `android/app/libs/teamspeak.aar` 文件存在且大小不为 0 2. 重新执行 Go 编译步骤 3. 在 IDEA 的 Logcat 中查看崩溃日志 4. 如果看到 `UnsatisfiedLinkError`,说明 .aar 中的 .so 文件架构不匹配或格式有问题 --- ## 附录:项目目录结构说明 ``` ts-mobile-go/ ├── go/ ← Go 源码(底层通信) │ ├── go.mod ← Go 的依赖声明(类似 package.json) │ ├── go.sum ← Go 的依赖锁文件(类似 package-lock.json) │ └── teamspeak/ │ └── bridge.go ← 核心:TeamSpeak 客户端桥接代码 │ ├── android/ ← Android 项目(IDEA 打开这个目录) │ ├── build.gradle.kts ← 根级构建配置(定义 Kotlin、AGP 版本) │ ├── settings.gradle.kts ← 项目设置(仓库地址、模块声明) │ ├── gradle.properties ← Gradle 参数(内存、编码等) │ ├── gradle/wrapper/ ← Gradle 版本管理(自动下载指定版本的 Gradle) │ └── app/ │ ├── build.gradle.kts ← 应用级构建配置(依赖、SDK 版本、签名等) │ ├── libs/ │ │ └── teamspeak.aar ← ← ← Go 编译产物,放在这里! │ ├── proguard-rules.pro ← 代码混淆规则 │ └── src/main/ │ ├── AndroidManifest.xml ← 应用声明(权限、入口 Activity 等) │ └── java/com/tsmobile/app/ │ ├── MainActivity.kt ← 应用入口 │ ├── TSBridge.kt ← Kotlin 调用 Go 的桥接层 │ ├── ui/ │ │ ├── components/ ← 可复用 UI 组件 │ │ ├── screens/ ← 各页面(连接、频道、聊天等) │ │ ├── navigation/ ← 页面路由 │ │ └── theme/ ← 主题颜色、字体 │ └── viewmodel/ ← 状态管理(ViewModel) │ ├── build.bat ← Windows 一键构建脚本 ├── build.sh ← Linux/macOS 一键构建脚本 └── BUILD.md ← 本文件 ```