# 04 — 构建环境与开发流程 > 现在**开发全程在 PC(Meowhome)上**:写码、编译、单测都在那边;**后端(Cyrene v2 主项目)也已迁到同一台 PC**。 > 本文记录 PC 的环境、镜像配置、日常流程和踩过的坑,换机器/重装时照抄即可。 > (旧开发机是一台性能较弱的 aarch64 Linux 容器,已停用;相关记录见 §5 备查。) > 最后更新:2026-10-03 --- ## 1. 机器分工 | 角色 | 机器 | 系统 / 架构 | 接入方式 | 干什么 | |---|---|---|---|---| | **开发 + 编译** | `Meowhome`(主机名 `AEiva`) | Windows / **AMD64** | `ssh Meowhome`(`cd.yeij.top:40022`,密钥 `~/.ssh/id_ed25519_meowhome`) | 写码、`gradlew.bat` 编译、跑单测 | | **后端** | 同一台 PC | — | 同上 | Cyrene v2 主项目 | > 后端现在跑在这台 PC 上;App 的「服务器地址」填 PC 上的后端地址(模拟器 `10.0.2.2`,真机走局域网 IP;**具体端口以主人给的为准**)。 --- ## 2. 版本组合(钉死,别随意升) | 项 | 版本 | 备注 | |---|---|---| | AGP | **9.2.1** | 9.x 起**内置 Kotlin**,不能再应用 `org.jetbrains.kotlin.android` | | Kotlin | **2.4.0** | 由 Miuix 0.9.3 的元数据牵引 | | Compose BOM | **2026.05.01** | 它 pin 的 `androidx.compose:ui:1.11.2` 正好等于 Miuix 0.9.3 在 Android 上的映射 | | Miuix | **0.9.3** | 只有 0.9.x;AAR 要求 `minCompileSdk=37` | | Gradle | **9.7.1** | wrapper 已配腾讯镜像 | | JDK | 本机 17 / PC **21** | AGP 9 需要 17+ | | minSdk / compileSdk / targetSdk | 33 / 37 / 37 | 33 起是为了解锁 `miuix-blur` | | buildToolsVersion | **37.0.0** | 必须显式指定,否则 AGP 默认找 36.0.0 | --- ## 3. 本机(aarch64 容器) SDK:`~/Android/Sdk` | 组件 | 来源 | |---|---| | `platforms/android-37.0` | 腾讯镜像 `platform-37.0_r02.zip` 手工解压 + **手写 `package.xml`** | | `build-tools/37.0.0` | **ARM64 原生版**,来自 [Commit451/android-arm-build-tools](https://github.com/Commit451/android-arm-build-tools)(release 资源需经 `https://ghproxy.net/` 代理下载),逐个校验 SHA256 | | `licenses/` | `android-sdk-license` / `android-sdk-preview-license`(标准哈希) | 本机专用配置放在 **`~/.gradle/gradle.properties`**(不进仓库): ```properties android.aapt2FromMavenOverride=/home/Aska/Android/Sdk/build-tools/37.0.0/aapt2 android.builder.sdkDownload=false ``` - 第一条:Google Maven 的 aapt2 只有 x86_64,aarch64 必须指向本地 ARM 版。 - 第二条:本机访问不了 `dl.google.com`,禁止 AGP 联网拉 SDK 清单(否则会卡住)。 镜像:Maven → 阿里云(`settings.gradle.kts`);Gradle 发行包 → 腾讯(`gradle-wrapper.properties`)。 --- ## 4. Meowhome(Windows) SDK:`C:\Users\Aska\AppData\Local\Android\Sdk`(**不在环境变量里**,是 Android Studio 默认位置) - `build-tools/37.0.0` 已有(Windows 原生 `aapt2.exe` / `aidl.exe` / `zipalign.exe` / `d8.bat`) - `platforms/android-37.0` **本机没有**,已用腾讯镜像 `platform-37.0_r02.zip` 补装,并补了 `package.xml` - `JAVA_HOME` = `C:\Program Files\Microsoft\jdk-21.0.11.10-hotspot\` 项目目录:`D:\Project\Code\Uni\Cyrene-For-Android` ```bat git clone ssh://git@git.yeij.top:2222/AskaEth/Cyrene-For-Android.git -b android . echo sdk.dir=C:/Users/Aska/AppData/Local/Android/Sdk> local.properties gradlew.bat assembleDebug ``` > `local.properties` 在 `.gitignore` 里,每台机器自己建。 PC 网络:`dl.google.com` 与腾讯镜像均可达(HTTP 200),但**按约定仍走国内镜像**。 ### 4.1 工作副本同步记录(2026-10-03) Windows 侧工作副本改为**从本机整树同步**(不再 `git clone`),已含 gitignored 的 `devdocs/`: - HEAD = `9bc45dc`(= `origin/android`),工作树干净;83 个源码/资源文件与本机逐字节一致(`local.properties` 例外,各机自建)。 - 验收:`gradlew.bat testDebugUnitTest --no-daemon` → **BUILD SUCCESSFUL**(JDK 21,49s)。 - 坑:仓库 `core.filemode` 在 Windows 侧要设 `false`(值为 Linux 的 `true` 时,`gradlew` 会因丢失可执行位一直显示 `M`,内容其实没变)。 - 同步方法:源码走 `tar | ssh` 解包,**中文文件名的 `devdocs/` 必须用 `scp`**(Windows 自带 bsdtar 解不出 UTF-8 文件名,会写出乱码副本)。 --- ## 5. 历史:上一阶段的真机流程(已停用) > 这一节是上一阶段「把手机当运行目标」的做法,**现在不需要了**,留档备查。 - 手机(OnePlus PLK110 / Android 16)已 root(KernelSU),`su -c` 可用。 - 装 APK(手机上的 Termux sshd,端口 2022): ```bash ssh -p 2022 aska@127.0.0.1 'cat > ~/cyrene.apk' < app-debug.apk ssh -p 2022 aska@127.0.0.1 'su -c "cp /data/data/com.termux/files/home/cyrene.apk /data/local/tmp/ \ && chmod 644 /data/local/tmp/cyrene.apk && pm install -r /data/local/tmp/cyrene.apk"' ``` - 截图 / UI 自动化: ```bash su -c "screencap -p /data/data/com.termux/files/home/shot.png; chmod 644 /data/data/com.termux/files/home/shot.png" # 取回:ssh ... 'cat .../shot.png' > local.png(scp 会被 Termux 启动 banner 污染,不能用) ``` **坑**:中文输入法会把 `//` 打成 `、`、`.` 打成 `。`,用 `input text` 填 URL 会失败。 --- ## 6. 日常流程 1. **本机**改代码(+ `devdocs/` 写文档,不进仓库) 2. `git commit` → `git push origin android` 3. **PC**:`cd /d D:\Project\Code\Uni\Cyrene-For-Android && git pull && gradlew.bat assembleDebug` 4. **取回**:`scp Meowhome:D:/Project/Code/Uni/Cyrene-For-Android/app/build/outputs/apk/debug/app-debug.apk .` 5. **装真机**(见 §5),看效果 --- ## 7. 踩坑记录 | 现象 | 原因 / 解法 | |---|---| | Maven 依赖拉不下来 | `dl.google.com` / `maven.google.com` 不通 → 仓库加阿里云镜像 | | `aapt2: 可执行文件格式错误` | aarch64 机器上跑的是 Google 的 x86_64 二进制 → 换 ARM64 版 + `aapt2FromMavenOverride` | | `Failed to find Platform SDK with path: platforms;android-37.0` | 手工解压的 SDK 包缺 `package.xml` → 补上(从 `android-35` 的模板改) | | `Failed to find Build Tools revision 36.0.0` | AGP 默认 build-tools 版本 → `buildToolsVersion = "37.0.0"` | | `The 'org.jetbrains.kotlin.android' plugin is no longer required` | AGP 9 内置 Kotlin → 移除该插件 | | `Unresolved reference 'KotlinSerializationConverterFactory'` | Retrofit 3 用 `@file:JvmName` 暴露,Kotlin 侧要用扩展函数 `json.asConverterFactory(...)` | | `MiuixIcons.Sidebar` 解析不到 | 实际是 `MiuixIcons.Basic.Sidebar`(文档与 API 有出入,以 AAR 为准) | | `/tmp` 放东西撑内存 | 本机 `/tmp` 是 tmpfs(内存盘)→ 临时文件放 `~/.cache/` | | 填 `http://…` 登录报「网络不可用」 | Android 9+ 默认禁止明文 HTTP,OkHttp 抛 `UnknownServiceException`(属 `IOException`)被映射成无网 → 加 `res/xml/network_security_config.xml` 放行 cleartext + 信任用户 CA | | 模拟器后台启动设了超时 → 到点被收割 | **别给要常驻的进程设超时**。踩过一次:1800s 上限到点把模拟器杀了,`adb reverse` 隧道一起没了 → 模拟器一律不加超时 | | `adb shell … /sdcard/…` 报 `ls: C:/Program: No such file or directory` | Git Bash 把设备路径当 Windows 路径改写 → 命令前加 `MSYS_NO_PATHCONV=1` | | 往 8080 打 `/api/v1/*` 拿到一张 HTML 404 | **这台机器的 8080 是个 PHP 应用**(`X-Powered-By: PHP/8.4.1`),Cyrene 在 **10942**。别把「看起来像后端的 HTML 404」当成「后端起不来」。详见 `05` 的后端一节 | | 模拟器里填 `10.0.2.2` 不通 | 这个 AVD **没有网络接口** → 用 `adb reverse` + `127.0.0.1`。详见 `05` 的模拟器一节 | | 提交时满屏 `LF will be replaced by CRLF` | 纯提示、无害(`core.autocrlf` 归一化);既有文件也一样,非某次改动引入 |