主人 2026-10-04 指示「项目仓库也可以写进去」。因此把 devdocs/ 从 .gitignore 移除并首次入库: - `05-开发进度与交接.md` —— 跨会话交接锚点:当前状态、易忘的实现约定、踩过的坑、实机验收方法 - `02-前后端协同事项.md` —— 与后端会话的**交换文档**(两边都会读写:我们登记缺口,对面写回执) - `01/03/04/06/07` + `DESIGN.md` —— 路线、客户端细化方案、构建环境、迁移说明、给后端会话的交接 **凭据扫描已过**:无账号口令、无 token/refreshToken 明文、无 API key 或私钥。 文档里只记「登录凭据不写进文档,问主人」这条口径本身。 (此前忽略它的理由已不成立:文档现在承担跨会话交接与前后端协同两件正事, 只留在本机磁盘会随机器丢失,而这批内容的价值恰恰在「后来人读得到」。)
139 lines
7.9 KiB
Markdown
139 lines
7.9 KiB
Markdown
# 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` 归一化);既有文件也一样,非某次改动引入 |
|