前言
Android 项目很适合交给 Codex 做一部分活,也很容易被 Codex 搞乱。
原因不复杂。Android/Kotlin 项目不只是几段 Kotlin 代码。它还有 JDK、Gradle、Android Gradle Plugin、Kotlin 插件、SDK、Manifest、资源文件、签名配置、模拟器和真机环境。任何一环对不上,./gradlew assembleDebug 就会停下来。
所以我不太建议让 Codex 直接「生成一个 APK」。这个说法太宽。
更稳的方式是把 Codex 放进一个短闭环里:读项目、做小改动、跑 Gradle、看错误、修补、留下 diff。
这篇记录的是我会怎么在 macOS 上组织这套流程。
1. 环境比提示词更要紧
Codex 写 Android 代码之前,本机环境要能独立构建项目。
我会把这几件事查清楚:
- macOS 版本和芯片架构。
- Android Studio 能不能正常打开项目。
- JDK 是不是项目需要的版本。
ANDROID_SDK_ROOT是否正确。sdkmanager、adb、emulator是否在 PATH 里。./gradlew assembleDebug是否能跑。
基本检查命令:
sw_vers
uname -m
java -version
./gradlew --version
Android SDK 常见路径是:
$HOME/Library/Android/sdk
可以把 SDK 工具加入 ~/.zshrc:
export ANDROID_SDK_ROOT="$HOME/Library/Android/sdk"
export PATH="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$PATH"
生效后检查:
source ~/.zshrc
sdkmanager --version
adb version
emulator -version
这些命令不通,Codex 后面给什么补丁都很难验证。
2. JDK、Gradle、AGP 不要靠猜
Android 项目里最常见的坑,不是 Kotlin 语法,而是版本组合。
JDK、Gradle、Android Gradle Plugin、Kotlin 插件、Compose Compiler 这些东西互相有要求。Codex 如果没有读到当前项目文件,很容易套一个旧模板。
让它改 Gradle 之前,我会让它看这些文件:
settings.gradle 或 settings.gradle.kts
build.gradle 或 build.gradle.kts
gradle/libs.versions.toml
app/build.gradle 或 app/build.gradle.kts
给 Codex 的要求可以写成这样:
阅读当前 Gradle 配置,保留项目现有版本体系。不要凭空升级 AGP、Gradle、Kotlin 或 Compose。需要新增依赖时,写清原因,并放到版本目录里。
这句话能挡住很多奇怪补丁。
如果项目已经有 Gradle Wrapper,命令行构建统一用它:
./gradlew assembleDebug
./gradlew testDebugUnitTest
不要让 Codex 混用本机全局 Gradle。Android 项目里,Wrapper 就是边界。
3. 模拟器和真机至少保留一个可用
Android 改动不能只看编译。
本地至少要有一种运行方式:模拟器或者真机。
模拟器相关命令:
sdkmanager --list
avdmanager list device
emulator -list-avds
Apple Silicon 机器上,系统镜像要匹配架构。一般会选择 arm64-v8a 镜像。具体能装哪些包,以 sdkmanager --list 输出为准。
真机调试检查:
adb devices
设备没有授权时,手机上会弹 RSA 授权窗口。这里不用让 Codex 猜,直接看 adb devices 输出就行。
我通常会把这个规则写给 Codex:
涉及 UI 或设备能力的改动,编译通过不算结束。能跑模拟器或真机时,需要说明使用哪个命令验证。
4. Codex 更适合做小块工程活
Android 项目里,我不太会让 Codex 接一整个 App。
比较适合它的任务是这种:
- 给现有页面补一个状态。
- 把网络请求接进 ViewModel。
- 修一个崩溃日志。
- 给一段业务逻辑补本地单测。
- 整理 Gradle 依赖。
- 给 release 构建补签名配置。
- 让 CI 跑
assembleDebug和单测。
这些任务都有一个共同点:改动可以被 Gradle 验证。
任务太大时,我会让它产出计划,但计划里不能只写漂亮话。要写文件、命令和风险。
示例:
检查当前 Android 项目,说明实现这个功能会涉及哪些文件、需要新增哪些依赖、构建命令是什么。暂时不要修改文件。
拿到计划后,挑一个最小切口开工。
5. 提示词要绑定构建命令
Android 任务的提示词,不需要写得很华丽。
我会固定写几个东西:目标、约束、输出格式、验证命令。
新增功能可以这样写:
目标:在现有 Android Kotlin 项目中实现一个简单的设置页,包含开关状态和保存逻辑。
约束:
- 保留当前 Gradle 和 Kotlin 版本,不做无关升级。
- 不引入新的三方库,除非项目里已经使用。
- 如果项目使用 Compose,就沿用 Compose;如果使用 XML,就沿用 XML。
输出:
- 直接修改项目文件。
- 说明修改了哪些文件。
- 运行 ./gradlew assembleDebug。
- 如果有业务逻辑,补一个本地单测并运行 ./gradlew testDebugUnitTest。
修 bug 可以这样写:
现象:{粘贴现象}
日志:{粘贴 logcat 或 stacktrace}
期望:{写清楚正确行为}
要求:
- 定位根因。
- 做最小修复。
- 不做无关重构。
- 修复后运行 ./gradlew assembleDebug。
- 能补测试时,补 src/test 下的本地单测。
这类 prompt 不漂亮,但 Codex 很容易执行。
6. 让 Codex 输出 diff,比输出解释更有用
Android 改动经常跨文件。
一个功能可能同时碰到:
app/build.gradle.ktsAndroidManifest.xmlMainActivity.ktViewModel.ktres/values/strings.xmlsrc/test/...
这种时候,长篇解释没什么用。diff 更重要。
我会要求 Codex 在收尾时给这几样东西:
请给出:
- 修改文件列表
- 核心行为变化
- 已运行的命令和结果
- 没能验证的部分
如果它没有跑构建,就必须说清楚。不要把「看起来没问题」当成结果。
7. APK 构建和签名不要混在一起
Debug APK 和 Release APK 是两件事。
Debug 构建:
./gradlew assembleDebug
Release 构建:
./gradlew assembleRelease
Debug APK 通常由开发环境自动签名。Release APK 要用自己的 keystore。
签名信息不要写死在仓库里。常见做法是用 keystore.properties,并把它加入 .gitignore。
示例:
storeFile=/absolute/path/release.jks
storePassword=change-me
keyAlias=release
keyPassword=change-me
Gradle 里读取这个文件,CI 里用环境变量或 Secret 注入。
我会给 Codex 明确写:
添加 Release 签名配置,但不要把 keystore、密码或真实路径提交到仓库。使用 keystore.properties 或环境变量,并更新 .gitignore。
这类要求不能省。
8. CI 里不要藏太多魔法
Android CI 最怕本地能跑,CI 不知道差在哪里。
GitHub Actions 里至少要固定:
- JDK 版本。
- Android SDK / Gradle 缓存策略。
- 构建命令。
- 测试命令。
- 签名密钥注入方式。
一个简单 workflow 可以长这样:
name: Android CI
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- uses: gradle/actions/setup-gradle@v4
- name: Build debug APK
run: ./gradlew assembleDebug
- name: Run unit tests
run: ./gradlew testDebugUnitTest
如果要做 release 签名,密钥走 GitHub Secrets。不要让 Codex 把 base64 后的 keystore 直接写进仓库。
9. Codex 常见翻车点
乱升版本
它可能会为了接入一个库,把 Kotlin、AGP、Gradle 都动了。
提示里要写:保留现有版本体系。新增依赖要说明原因。
编译没跑
Android 代码看起来对,不代表能过 Gradle。
./gradlew assembleDebug 是最低门槛。
Manifest 漏权限
网络、相机、定位、文件访问,都会牵涉 Manifest 权限。涉及系统能力的改动,要让 Codex 检查 Manifest。
Compose 和 XML 混写
项目用 Compose,就沿用 Compose。项目用 XML,就沿用 XML。混着写不是不行,但要有明确理由。
测试写得太假
有些测试只是创建对象,不验证行为。
要求它覆盖具体 bug 或业务规则,不要只补测试文件数量。
签名信息进仓库
这个问题最麻烦。
任何 keystore、密码、token、API key,都不应该进 Git。
10. 我会反复使用的几段话
检查项目:
阅读当前 Android 项目结构,说明 Gradle 配置、JDK 要求、主要模块、构建命令和测试命令。不要修改文件。
小功能:
在现有 Android Kotlin 项目中实现 {功能}。保留当前技术栈和版本,不做无关升级。完成后运行 ./gradlew assembleDebug,并说明修改文件和验证结果。
修崩溃:
根据这段 logcat 定位崩溃根因,做最小修复。不要重构无关代码。修复后运行 ./gradlew assembleDebug;如果逻辑适合单测,补 src/test 测试并运行 ./gradlew testDebugUnitTest。
Release 签名:
为 Android 项目添加 Release 签名配置。不要提交 keystore 或密码。使用 keystore.properties 或环境变量,并更新 .gitignore。完成后运行 ./gradlew assembleRelease。
CI:
添加 GitHub Actions Android CI,固定 JDK 17,使用 Gradle 缓存,运行 assembleDebug 和 testDebugUnitTest。不要把任何签名密钥写进 workflow。
结语
Codex 做 Android,不适合拿来赌一次性生成完整 App。
它更适合接一段段小工程活:改 Gradle、补页面、修崩溃、写测试、处理签名、搭 CI。
每段任务都绑住一个命令。能编译,能测试,能看到 diff。
这样用起来没那么神奇,但靠谱很多。