执行摘要
本报告面向“macOS 上用 Codex 更好地写 Android Kotlin APK”的真实工程流程:先把 Android 工具链(Android Studio/SDK/JDK/Gradle/模拟器与真机)搭牢,再把 Codex(App/CLI/IDE 扩展/API)嵌入到“需求 → 生成 → 编译 → 测试 → 迭代 → 签名发布 → CI/CD”的闭环中。核心结论是:在 Android/Kotlin 这类依赖强、编译器与构建系统约束多的领域,Codex 的价值主要来自“把高频机械劳动(样板代码、Gradle 接入、测试骨架、修复回归)自动化”,而不是一次性全量生成;因此“可重复的提示模板 + 明确的版本/约束 + 自动构建与测试门禁 + 小步迭代”会显著提高成功率与可维护性。
在工具链方面:Android Studio 对 Mac 的最低系统要求为 macOS 12,推荐使用最新 64 位 macOS,并且官方提示正在逐步淘汰 Intel Mac 的支持、推荐 Apple Silicon。 在构建环境方面,从 Android Gradle Plugin(AGP)8.x 起常见要求是 JDK 17,最新 AGP(例如 9.1.0)也将 JDK 17 作为兼容与默认版本之一;同时最新 Gradle 本身也要求 JDK 17+ 运行。 在模拟器方面,macOS 上 Android Emulator 使用系统自带的 Hypervisor.Framework,并且 macOS 11 起不再支持 Intel HAXM;在 Apple Silicon 上应选用 arm64‑v8a 系统镜像以满足加速条件。
在 Codex 接入方面,OpenAI 的 Codex 可以通过 Codex App(macOS Apple Silicon)、Codex CLI(开源,本地运行,可读写代码并执行命令)、IDE 扩展(如 VS Code)、云端 Codex、以及 OpenAI API(Responses API) 等路径落地。官方建议进行代码生成或工程任务时优先用最新 GPT‑5 系列(例如 gpt‑5.4)作为通用默认模型;也存在面向 Codex 工作流的专用编码模型(如 gpt‑5.3‑codex)。
报告还给出:可复制的 Mac 端到端环境安装命令、3 个可复用提示模板、3 个“完整示例提示(含预期输出形态)”、一套“从 Codex 输出到签名 APK”的脚本与 GitHub Actions(自托管 Mac Runner)示例、以及常见错误排障表。
Mac 环境与 Android 工具链前置条件
未指定项声明:用户未提供 macOS 版本、CPU 架构(Intel/Apple Silicon)、Android Studio 版本、目标 minSdk/targetSdk、是否使用 Jetpack Compose 等。以下将基于官方要求给出“推荐默认”和“可替换项”,并说明如何自检与调整。
关键前置条件与版本策略
macOS 与硬件:Android Studio 在 Mac 的最低 OS 要求为 macOS 12,建议使用最新 64 位 macOS;同时官方说明正在逐步淘汰 Intel Mac,推荐 Apple Silicon。 这会影响你对“模拟器镜像架构(arm64‑v8a vs x86_64)”与“Codex App 是否可用”的选择。
JDK / Gradle / AGP:Android 构建由 Gradle + Android Gradle Plugin 驱动。Android 官方文档明确提醒:AGP 的最低 JDK 版本要看兼容表,且给出示例——AGP 8.x 需要 JDK 17;AGP 9.1.0 的兼容信息也列出 JDK 17。 同时,Gradle 官方安装文档也强调运行 Gradle 需要 JDK 17 或更高版本。
实践建议:在 macOS 上尽量把“IDE 使用的 JDK”和“Gradle 构建使用的 JDK”统一到 17,避免“IDE 能 Sync,但命令行 ./gradlew 失败”这类割裂问题。
Kotlin 插件变动(重要但易忽略):Kotlin 官方兼容指南指出:Kotlin 2.3.0 起,在 AGP 9.0.0+ 环境下 org.jetbrains.kotlin.android(kotlin-android)插件被标记为 deprecated,因为 AGP 9+ 内置了 Kotlin 支持。
实践建议:让 Codex 生成/修改 Gradle 时,要显式告诉它你使用的 AGP/Kotlin 版本与期望写法;否则它很可能生成“旧模板”导致 warning 或未来升级风险(见后文提示工程)。
Android SDK 与命令行工具:Android SDK 由多个包组成,常用命令行工具包括 sdkmanager(安装/更新 SDK 包)、avdmanager(管理 AVD)、adb(调试桥)。sdkmanager 与 avdmanager 在 Android 官方工具文档中分别有清晰定义。
模拟器与真机:
- 模拟器:macOS 上 Emulator 使用 Hypervisor.Framework,且 macOS 11 起不再支持 HAXM。
- Apple Silicon:要获得 VM 加速,需要使用 arm64‑v8a 系统镜像(API 21+)。
- 真机:官方建议通过 USB 或 Wi‑Fi 调试,并在设备上开启开发者选项与 USB/Wi‑Fi 调试;连接时会出现 RSA 授权弹窗。
Mac 端到端安装与配置步骤(含命令)
下面给出“尽量可复制”的步骤。若某一步与你的实际目录不同,请以 Android Studio 的 SDK Manager 显示路径为准(不需要猜)。
系统自检与目录准备
# 0) 查看 macOS 版本与 CPU 架构(Intel: x86_64;Apple Silicon: arm64)
sw_vers
uname -m
# 1) 建议准备一个专用开发目录
mkdir -p ~/Dev/android
cd ~/Dev/android
Android Studio 在 Mac 的安装方式是 DMG 拖拽到 Applications 并运行向导,官方安装步骤明确包含“通过 Setup Wizard 下载 Android SDK 组件”。
配置 Android SDK 环境变量与 PATH
Android SDK 在 macOS 上常见默认路径为 ~/Library/Android/sdk(以你机器实际为准)。为了让 sdkmanager/adb/emulator 在终端可用,建议设置 ANDROID_SDK_ROOT 并把常用目录加入 PATH。
# 2) 写入 zsh 配置(macOS 默认 shell 通常为 zsh)
cat <<'EOF' >> ~/.zshrc
# Android SDK
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"
EOF
source ~/.zshrc
# 3) 验证(若提示 command not found,说明 cmdline-tools/platform-tools 还没装)
sdkmanager --version || true
adb version || true
emulator -version || true
说明:
sdkmanager是用于查看/安装/更新 Android SDK 包的官方命令行工具;如果你使用 Android Studio,也可在 IDE 内管理 SDK,但命令行在自动化/CI 场景很关键。
安装 SDK 包与接受许可证
以 AGP 9.1.0 的兼容信息为例,它期望的 SDK Build Tools 默认版本包含 36.0.0,并且支持最大 API level 36.1。你可以按此安装(也可按项目需要改成其它 API/Build Tools 版本)。
# 4) 先查看可用包(用于确认你机器可装到哪些 platforms/build-tools/system-images)
sdkmanager --list
# 5) 安装常用组件(platform-tools/构建工具/平台/模拟器)
sdkmanager \
"platform-tools" \
"emulator" \
"platforms;android-36" \
"build-tools;36.0.0"
# 6) 接受 licenses(自动化时常见)
yes | sdkmanager --licenses
命令行工具包的安装与更新流程、以及 cmdline-tools;latest 的安装命令,在 Android 官方 release notes 中有说明。
创建并启动 Android Emulator(可选)
avdmanager 是官方命令行工具,用于创建与管理 AVD。
Apple Silicon(arm64)建议:根据官方 Emulator 加速文档,ARM64 主机需要使用 arm64‑v8a 系统镜像(API 21+)以满足加速要求。
# 7) 安装系统镜像(示例:Google APIs + arm64-v8a;实际可用项以 sdkmanager --list 为准)
sdkmanager "system-images;android-36;google_apis;arm64-v8a"
# 8) 创建 AVD(示例设备 pixel_6;可用设备 id 用 avdmanager list device 查看)
avdmanager list device | head -n 50
avdmanager create avd \
-n Pixel_API_36 \
-k "system-images;android-36;google_apis;arm64-v8a" \
-d pixel_6
# 9) 启动模拟器
emulator -list-avds
emulator @Pixel_API_36
macOS 上 Emulator 使用 Hypervisor.Framework;并且 macOS 11 起不再提供 HAXM 加速选项。
连接真机(推荐至少做一次)
官方“在硬件设备上运行”指南给出:在设备设置里启用开发者选项与 USB 调试(或 Wi‑Fi 调试),并确保系统能识别设备;adb 文档也说明连接设备会弹出 RSA 授权对话框。
# 10) 插线后检查设备是否被 adb 识别
adb devices
Codex 接入方式与在 Mac 上的落地形态
Codex 的官方“入口矩阵”
从官方文档视角,Codex 是一个可在多种界面中使用的编码代理:IDE、CLI、Web/Cloud、以及在 CI/CD 中与 SDK/API 集成。
Codex App:官方 Quickstart 明确 Codex App 可在 macOS 使用,但强调是 **macOS(Apple Silicon)**版本可用。同时,OpenAI 的官方产品文章也描述了 Codex App 的定位:用于多代理并行、工作区管理,以及与 CLI/IDE 历史和配置共享。
Codex CLI:官方 CLI 文档强调它可以在选定目录中读取、修改并运行代码;同时它是开源且本地运行。 这使它非常适合 Android 项目这种“必须落地到文件系统 + 必须跑 Gradle”的场景(比纯聊天更工程化)。
Codex IDE 扩展:官方提供 Codex IDE extension,并明确 VS Code 扩展可用于 macOS。 若你不想在 Android Studio 内嵌 AI(或不满足兼容性),可以采用“Android Studio 编译运行 + VS Code/Codex 进行推理与批量改动”的双 IDE 流程。
云端 Codex:官方 Quickstart 提供 chatgpt.com/codex 的云端入口,并描述了连接 GitHub repo、运行任务、review diff 与发 PR 的流程。
模型与 API:把 Codex 能力嵌进你自己的工具链
官方 OpenAI API “Code generation”指南指出:Codex 在 GPT‑5 系列模型上效果最佳(如 gpt‑5.4),也存在为 Codex 工作流设计的专用编码模型(如 gpt‑5.3‑codex);并给出使用 Responses API 的示例调用方式。
这对 Android 工程意味着:你可以把“生成补丁(git diff)→ 应用 → ./gradlew build/test”做成脚本,在本机或 CI 中自动跑,形成可重复的 AI 辅助构建流水线。
插件、Skills 与 MCP:让 Codex 访问外部工具与内部规范
Codex 的插件体系(Plugins)用于把 skills、应用集成、MCP servers 打包成可复用工作流;官方示例包含 Gmail、Google Drive、Slack 等。 对 Android 项目而言,MCP 更常见的价值在于:把“内部依赖/接口文档/代码规范/安全扫描”通过统一协议提供给代理,减少 hallucination 与错误依赖猜测。
JetBrains/Android Studio 生态:兼容性要“验证而非假设”
JetBrains 官方博客在 2026 年披露 Codex 已集成到 JetBrains IDE 的 AI chat 里,并支持使用 JetBrains AI 订阅、ChatGPT 账号或 OpenAI API key。由于 Android Studio 基于 IntelliJ 平台但有独立发布节奏与插件兼容限制,你应把“是否能在 Android Studio 内直接使用该集成”视为需要在当前 Android Studio 版本上验证的事项,而不是让 Codex 或模型自行猜测。
本地模型与代理:在 Codex 中“可选的”本地化路径
严格讲,Codex 的主路径是面向 OpenAI 模型与其编码代理工作流;但官方 Codex Advanced Config 提到:如果你需要把内置 OpenAI provider 指向代理/路由器/特定区域的 base URL,可在 config.toml 中设置 openai_base_url。 这为“内网代理、审计网关、甚至 OpenAI‑compatible 的本地模型服务”提供了可探索接口。
两类常见本地推理基础设施(用于“隐私优先/离线/成本控制”):
- Ollama:其 macOS 官方安装文档给出 DMG 安装方式;并且下载页写明 macOS 版要求(例如 macOS 14+ 的要求可能随版本变化)。
- LM Studio:官方文档说明其可在 macOS 本地运行模型,并提供包括 OpenAI‑compatible 在内的兼容 API endpoint。
如果你希望把多模型统一到“OpenAI 兼容 API”之下,可使用 LiteLLM Proxy(官方文档将其描述为自托管的 OpenAI‑compatible gateway,支持路由多 provider)。
关键风险提示:即使接口“兼容”,Codex/代理对某些高级能力(如工具调用、流式事件、token accounting、特定字段)可能有假设;因此应先在一个小仓库验证(例如只做“生成 git diff”),再迁移到真实 Android 工程。
面向 Kotlin/Android 的提示工程
Android 项目对“构建可通过”的要求非常苛刻:依赖版本、Gradle/AGP/Kotlin compatibility、manifest 权限、资源命名、测试运行环境等,任何一处不一致都会导致失败。Android 官方强调:可用 ./gradlew 在命令行执行所有 build tasks,并且构建输出路径固定;这意味着你可以把“提示的输出格式”绑定到“可自动验证的命令与结果”。
Kotlin/Android 提示工程的核心原则
把“约束”显式写进提示,而不是指望模型记得。尤其要显式写:
- 目标构建命令:至少
./gradlew assembleDebug,最好再加./gradlew testDebugUnitTest/./gradlew connectedDebugAndroidTest(能跑的话)。Android 官方文档明确assembleDebug的用法与输出目录。 - 版本约束:JDK 17、AGP/Gradle/Kotlin 版本组合(避免生成“过时模板”)。
- 技术栈边界:Compose vs XML、是否用 Hilt、是否允许引入 Retrofit/Room 等。
- 输出格式:让 Codex 输出 git diff 或“逐文件内容”,并附“运行命令清单”。Codex Quickstart 强调使用 Git checkpoints 以便回滚,意味着 diff/小步更安全。
建议默认输出为“可审阅的补丁(git diff)”:Android 改动往往跨多文件(Gradle、Manifest、Kotlin、资源、测试)。补丁输出天然适配 code review,也更容易定位“哪一处导致 build break”。
先让 Codex 产出测试与可观测点,再产出功能:Android 官方区分本地单元测试(JVM 上跑)与 instrumentation/UI 测试(设备/模拟器上跑);提示中明确要求其中一种,会减少“只写功能不写验证”的漂移。
三个可复用提示模板
下面模板支持三种“工作单元”:新增功能、修复 bug、搭建工程骨架。你可以在 Codex App/CLI/IDE extension 里直接使用,也可以作为 OpenAI API 的 system/user messages。
模板一:新增功能(基于现有 Android Studio 项目,补丁输出)
【上下文】
你在一个 Android Studio 生成的 Kotlin 项目中工作(单模块 app)。
请先读取并遵守:gradle/libs.versions.toml(如果存在)、settings.gradle(.kts)、build.gradle(.kts)、app/build.gradle(.kts)、AndroidManifest.xml。
【目标】
实现:<用 2~5 条 bullet 描述的可验证功能>。
【约束】
- JDK: 17(不要引入需要更高/更低 JDK 的方案)
- 构建必须通过:./gradlew assembleDebug
- 若涉及网络:补齐 INTERNET 权限,并提供最小可运行的 UI
- 不引入不必要的新三方库;若必须新增依赖,说明原因并固定版本,或统一走版本目录(`libs.versions.toml`)
【质量门禁】
- 至少新增 1 个本地单元测试(src/test)或 1 个 UI/Instrumentation 测试(src/androidTest)
- 代码遵循 Kotlin 风格,避免伪代码
【输出格式(必须严格遵守)】
1) 输出一个 git diff(包含所有修改/新增文件)
2) 输出我在 macOS 终端执行的命令列表(顺序执行即可复现)
依据:命令行构建与输出目录、debug/release 的概念与签名要求来自 Android 官方文档。
模板二:Bug 修复(先复现/加测试,再最小修复)
【问题】
现象:<用户可见现象>
日志/堆栈:<粘贴 logcat/stacktrace>
期望:<期望行为>
【项目约束】
- 不改动公共 API(除非必要)
- 优先最小改动(small diff),避免无关重构
- 构建必须通过:./gradlew assembleDebug
- 新增/更新测试以覆盖该 bug:优先 src/test;若必须用设备能力才写 androidTest
【输出格式】
1) 先给出“根因假设 -> 验证方式 -> 最小修复策略”(3~8 行)
2) 给出 git diff
3) 给出命令:./gradlew testDebugUnitTest(若可) + ./gradlew assembleDebug
依据:本地单元测试在本机 JVM 运行、可更快验证逻辑;instrumented tests 运行在设备/模拟器上。
模板三:工程骨架生成(把“版本与结构”锁死)
【目标】
生成一个“可编译运行”的 Android Kotlin 项目骨架,使用 <Compose 或 XML>。
- applicationId: <your.app.id>
- minSdk: <X>
- targetSdk/compileSdk: <Y>
- 构建命令:./gradlew assembleDebug 必须成功
- 输出:文件树 + 关键文件完整内容(Gradle/Manifest/MainActivity/一个示例 screen)
【关键约束】
- 固定 Gradle/AGP/JDK/Kotlin 组合,不要使用不明确的 “latest”
- 说明需要安装的 Android SDK packages(platforms/build-tools 等)
【输出格式】
- 先给目录树
- 再按文件路径逐个输出内容(每个文件用代码块标记)
- 最后给出 macOS 终端命令:安装 SDK(sdkmanager)-> 构建 -> 安装到设备(adb 可选)
依据:sdkmanager/avdmanager 的职责、以及 ./gradlew assembleDebug 的官方用法。
从提示到可运行项目的生成工作流
这部分给出一个可操作且可审计的工作流:让 Codex 产出可回滚的 diff,并用 Gradle 任务作为“事实裁判”。Android 官方对命令行构建的支持意味着这条链路天然适合自动化。
推荐工作流:最小闭环 + 版本钉死 + Git checkpoints
Codex Quickstart 明确建议在每次任务前后创建 Git checkpoints,原因是 Codex 能对代码库做修改;这正适用于 Android 项目“多文件联动、容易改崩”的特性。
flowchart TD
A[需求/Issue] --> B[确定约束: minSdk/targetSdk/Compose/依赖策略]
B --> C[创建或打开 Android Studio 项目]
C --> D[Git checkpoint: clean state]
D --> E[用模板提示 Codex 生成 git diff]
E --> F[应用 diff + 人工快速 review]
F --> G[./gradlew assembleDebug]
G -->|失败| H[把错误日志回灌给 Codex: 最小修复]
H --> E
G -->|成功| I[测试: testDebugUnitTest / connectedDebugAndroidTest]
I -->|失败| H
I -->|成功| J[Release: 签名 + R8 + assembleRelease]
J --> K[产物归档/CI/CD 发布]
Mermaid 基本语法与 GitHub 对 Mermaid 渲染的支持在其官方文档中有说明。
三个端到端示例提示(含预期输出形态)
以下示例刻意选择“构建可验证”的目标;预期输出强调 文件改动点 与 可执行命令,以便你快速判断生成是否可信。
示例提示一:两页 Compose + 导航 + 最小 UI 测试(可 assembleDebug)
适用场景:你已用 Android Studio 创建了一个最小 Compose 项目(Empty Activity),现在要让 Codex 以“补丁”方式加功能与测试。
你在一个 Android Studio 生成的 Jetpack Compose 项目中工作(单模块 app)。
目标:实现两页应用:
1) HomeScreen:显示 "Hello Codex";有计数器文本 "Count: X";有按钮 "Increment" 每次 +1;
2) SettingsScreen:显示 "Settings";有返回按钮回到 Home。
要求:
- 使用 Navigation Compose(NavHost)
- 使用 Material3
- 添加 1 个 Compose UI instrumentation test:点击 Increment 后 Count 文本变化
- 构建必须通过:./gradlew assembleDebug
输出必须是:
(1) 一个 git diff(包含 Gradle 依赖、Kotlin 源码、测试)
(2) macOS 终端命令列表(含运行测试的命令)
预期输出(摘要):
app/build.gradle.kts:新增 Navigation Compose 与 Compose UI test 相关依赖;确保 androidTest 依赖完整。- 新增
HomeScreen.kt/SettingsScreen.kt/AppNavHost.kt或类似文件;MainActivity.kt引入 NavHost。 app/src/androidTest/...:新增 Compose UI test(使用 Compose test framework;Android 官方明确 instrumented tests 常用于 UI 测试,并提到 Espresso 或 Compose Test。)- 命令清单至少包含:
./gradlew assembleDebug(Android 官方明确用法)。./gradlew connectedDebugAndroidTest(需要启动 emulator 或连接真机;属于 instrumented tests)。
示例提示二:OkHttp/Retrofit 网络请求 + ViewModel + 本地单测(可 assembleDebug)
适用场景:你要快速搭一个“网络列表页”的可运行 APK,同时用本地单测验证关键逻辑(避免只靠眼看 UI)。
在现有 Android Kotlin 项目中新增一个“文章列表”功能页(Compose)。
功能:
- 启动后请求一个 HTTP JSON 列表(你可以用一个公开示例 API URL,或在代码里提供可替换 baseUrl 常量)
- 用 ViewModel + StateFlow 管理状态(Loading / Success / Error)
- UI:Loading 显示进度;Success 用 LazyColumn 列表展示 title;Error 显示错误文案与重试按钮
工程要求:
- 补齐 AndroidManifest 的 INTERNET 权限
- 至少写 1 个本地单元测试(src/test):对 Repository/UseCase 的状态转换进行测试(通过 fake data source,不要依赖真网络)
- 构建必须通过:./gradlew assembleDebug && ./gradlew testDebugUnitTest
输出:
1) git diff
2) 命令列表(包含本地单测与 assembleDebug)
预期输出(摘要):
AndroidManifest.xml增加<uses-permission android:name="android.permission.INTERNET" />(网络访问的必要条件;虽属常识,但建议你让 Codex 在 diff 中显式体现,便于 code review)。src/main下:新增ApiService/Repository/ViewModel;UI 层用collectAsState()或等价方式订阅状态。src/test:新增本地单测;Android 官方解释本地单元测试在工作站 JVM 运行、执行更快,但无法直接与 Android framework 交互。- 命令清单至少包含:
./gradlew testDebugUnitTest与./gradlew assembleDebug。
示例提示三:把项目改造成“可自动签名的 Release APK”并启用 R8
适用场景:你已经有可运行的 debug APK,现在要把“签名、混淆/压缩、可发布产物”工程化(并且不把密钥写死到仓库里)。
请把当前 Android 项目改造成可在命令行一键输出“已签名 release APK”:
要求:
- 使用 keystore.properties 存储签名信息(不要把密码硬编码进 build.gradle.kts)
- app/build.gradle.kts 中配置 signingConfigs.release,并让 release buildType 使用它
- release 开启 R8:isMinifyEnabled = true,isShrinkResources = true,并使用默认的 proguard-android-optimize.txt + 自定义 proguard-rules.pro
- 保持 debug 不启用 shrink
- 输出必须是 git diff + 命令列表:
./gradlew assembleRelease
并在说明中告诉我 release APK 的输出路径
预期输出(摘要):
- 根目录新增
keystore.properties示例文件(但应加入 .gitignore,避免泄露)。Android “Sign your app” 文档明确建议将签名信息移出 build files,并给出keystore.properties与 Kotlin DSL 读取示例。 app/build.gradle.kts:按 Android 官方示例加载Properties()并在signingConfigs中引用。releasebuildType:启用 R8/资源压缩与proguard-android-optimize.txt(Google 官方博客提醒要使用 optimize 文件而非旧的 proguard-android.txt,以启用优化)。- 输出路径:Android 官方命令行构建文档指出 APK 会出现在
module/build/outputs/apk/。
构建、签名与 R8 优化集成
Gradle 构建:以 Gradle Wrapper 为唯一入口
Android 官方强调:你可以用 Gradle wrapper(macOS 上是 ./gradlew)执行项目所有任务,并建议在项目根目录运行;并详细介绍 assembleDebug 的用法与产物目录。
实践建议:让 Codex 永远以 ./gradlew 为准(而不是系统 gradle),并在提示中强制它输出“我该运行哪些 gradle tasks”。
常用命令(示例):
# 查看任务
./gradlew tasks
# Debug APK
./gradlew assembleDebug
# Release(签名与配置见下)
./gradlew assembleRelease
签名:区分 Debug 自动签名与 Release 私钥签名
Android “Sign your app” 文档明确:Android Studio 会自动为 debug 构建生成并使用 debug.keystore(默认在 $HOME/.android/debug.keystore),该证书“insecure by design”,大部分应用商店(包括 Google Play)不接受用于发布。
命令行构建文档也强调:debug 构建使用 SDK tools 提供的 debug key 自动签名,而 release 必须用你的私钥签名。
推荐做法:使用 keystore.properties + Gradle Kotlin DSL 加载(官方给出 Kotlin 示例)。
// app/build.gradle.kts(示例片段:按官方建议把敏感信息放到 keystore.properties)
import java.util.Properties
import java.io.FileInputStream
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = Properties().apply {
load(FileInputStream(keystorePropertiesFile))
}
android {
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["storePassword"] as String
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
}
}
}
该模式的要点是:
keystore.properties不进版本库,仅在本机与 CI secrets 中注入。Android 官方明确提出“Remove signing information from your build files”的动机与步骤。
如果你要上 Google Play,官方文档还强调首次发布时需要配置 Play App Signing,并提供“生成 upload key/keystore”“生成 upload certificate(keytool -export -rfc)”等流程。
R8/ProGuard:把“发布构建优化”当成默认工作
Android 官方性能优化文档明确:R8 是应用优化器,可进行代码/资源压缩与优化;并强调 release build 上应启用优化(但测试/库场景需谨慎)。
官方博客进一步给出实践要点:要使用 proguard-android-optimize.txt(而不是旧的 proguard-android.txt)以启用 R8 的优化。 另一个官方博客提到:从 AGP 8.0 起 R8 full mode 默认开启,并提示避免在 gradle.properties 中禁用。
同时,Guardsquare 的 ProGuard 手册提醒:Android 默认 shrinker R8 兼容 ProGuard keep rules,但 ProGuard/R8 不是“安全加固工具”,不要把混淆当成防逆向的充分手段。
调试、测试与质量门禁
调试:真机与模拟器的最低必备命令
连接真机的官方流程:在设备上开启 Developer options 与 USB debugging / Wireless debugging;然后用 adb devices 检查连接。
adb 文档强调:Android 4.2.2+ 连接时会要求你在设备上确认 RSA key,以防止未授权调试。
adb devices
adb install app/build/outputs/apk/debug/app-debug.apk
(命令行构建文档给出 adb install 的安装方式,并说明 APK 输出目录位置。)
Android Studio 的调试能力(断点、变量检查等)在官方调试文档中说明。
测试分层:本地单测优先,UI 测试覆盖关键路径
本地单元测试(src/test):Android 官方指出它运行在工作站 JVM,更快;但无法直接与 Android framework 交互,并解释了 Mockable Android library 的限制。
Instrumented/UI 测试(src/androidTest):Android 官方指出 UI 测试通常是 instrumented tests,并提到 Espresso 或 Compose Test 等框架。
建议把以下命令作为“Codex 生成代码后的默认门禁”:
# 编译(最硬指标)
./gradlew assembleDebug
# 本地单测(快速反馈)
./gradlew testDebugUnitTest
# UI/仪器测试(需要模拟器或真机;CI 可按条件启用)
./gradlew connectedDebugAndroidTest
CI/CD 自动化与安全治理
本节目标:给出从“Codex 产出代码”到“稳定生成签名 APK”的自动化路径,并把 API key / keystore 等敏感信息纳入治理。
从 Codex 输出到签名 APK 的本地自动化脚本示例
Android 官方文档不仅说明如何签名,还明确建议把签名信息迁移到 keystore.properties,并在 Gradle 中读取。 利用这一点,你可以在 macOS 上用一个脚本实现“解码 keystore → 写入 properties → assembleRelease”。
#!/usr/bin/env bash
# scripts/build_signed_apk.sh
set -euo pipefail
# 约定:CI/本机通过环境变量注入
# KEYSTORE_B64: base64 编码的 .jks
# KEYSTORE_PASSWORD / KEY_PASSWORD / KEY_ALIAS: 签名参数
# (不要写死在仓库里)
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"
mkdir -p .secrets
if [[ -n "${KEYSTORE_B64:-}" ]]; then
echo "$KEYSTORE_B64" | base64 --decode > .secrets/release.jks
fi
cat > keystore.properties <<EOF
storePassword=${KEYSTORE_PASSWORD:-}
keyPassword=${KEY_PASSWORD:-}
keyAlias=${KEY_ALIAS:-}
storeFile=${ROOT_DIR}/.secrets/release.jks
EOF
# 建议把 keystore.properties 与 .secrets/ 加入 .gitignore
./gradlew clean assembleRelease
echo "Release APK 输出目录(以模块 app 为例):app/build/outputs/apk/release/"
依据与可验证点:
- Release 构建需要签名配置、且 debug keystore 不可用于发布:Android 官方签名文档。
- APK 输出目录:命令行构建官方文档明确指出
module/build/outputs/apk/。
GitHub Actions:在“自托管 Mac Runner”上做 Android CI
如果你的目标是“CI/CD 自动化在 Mac 上运行”,最稳定的方式通常是把你自己的 Mac 作为 self-hosted runner:这样可以复用你已安装的 Android SDK/模拟器/签名材料,不必在每次 workflow 里下载大体积 SDK。
同时,GitHub 官方文档在“使用 Gradle 构建与测试”教程中提到:gradle/actions/setup-gradle 可负责缓存与提供 Gradle 执行摘要。
下面给一份“从 push/PR 到产出签名 APK artifact”的最小示例(自托管 Mac):
# .github/workflows/android-macos-selfhosted.yml
name: android-macos-selfhosted
on:
push:
branches: [ "main" ]
pull_request:
jobs:
build:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- name: Set up Java 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6
- name: Build + Unit Tests
run: |
./gradlew testDebugUnitTest
./gradlew assembleDebug
- name: Build signed Release APK
env:
KEYSTORE_B64: ${{ secrets.KEYSTORE_B64 }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
run: |
chmod +x scripts/build_signed_apk.sh
scripts/build_signed_apk.sh
- name: Upload APK artifact
uses: actions/upload-artifact@v4
with:
name: apk-release
path: app/build/outputs/apk/release/*.apk
为什么这样写:
actions/setup-java用于在 Actions runner 上安装并配置 Java;其 README 明确涵盖 Gradle 场景。gradle/actions/setup-gradle官方说明其用于配置 Gradle 并利用 Actions cache。- 本地/CI 的 Gradle build cache 概念与收益在 Gradle 官方文档中说明(可选开启)。
若你希望在 CI 跑 emulator instrumentation tests,可参考
ReactiveCircus/android-emulator-runner(支持 Linux/macOS 硬件加速模拟器)。 同时 GitHub 也曾公告 Linux runners 的硬件加速 Android virtualization 支持改进。
Fastlane:把“构建 + 上传分发”标准化
Fastlane 官方 Android 文档推荐用 Bundler 或 Homebrew 安装(macOS 可用 brew,但更推荐 Bundler 管理依赖)。
Fastlane 的 gradle action 用于执行 Gradle 相关任务;而 upload_to_play_store(supply)用于上传 APK/AAB 与 metadata 到 Google Play。
一个最小 Fastfile 示例(仅展示思路):
# fastlane/Fastfile
default_platform(:android)
platform :android do
desc "Build signed release APK"
lane :release_apk do
gradle(
task: "clean assembleRelease"
)
end
end
(等你把签名信息按 keystore.properties/CI secrets 管好后,这条 lane 就能稳定产出 release。)
安全与隐私:API keys、密钥、以及 Codex 的权限边界
OpenAI API key 管理:官方“Production best practices”强调不要把 API keys 暴露在代码或公开仓库里,应使用环境变量或 secret management;并指向“API key safety best practices”。 官方 Quickstart 也给出“在终端导出 API key 环境变量”的流程。
建议:为团队成员使用独立 key,按环境分项目(staging vs production),并监控 usage。
Codex 权限与审计:官方 best practices 提到 Codex 的 sandboxing 与 approval mode 是关键安全旋钮,应默认保持严格,仅对可信 repo 放宽。 Codex Advanced Config 还提供 shell 环境变量继承/排除策略,并提到默认存在 KEY/SECRET/TOKEN 过滤;以及可选 OpenTelemetry 事件导出且默认对 prompt 内容做 redaction(除非显式开启)。
建议:在 Android 项目中,把 keystore、local.properties、.env、服务端密钥等全部列入“永不进提示/永不进仓库”的敏感清单;并通过 Codex 的 approval/sandbox 与 repo 规范(如 AGENTS.md、.codex/config.toml)固化。
局限性、失败模式与排障
Codex 在 Android/Kotlin 场景的典型失败模式与缓解
版本漂移(最常见):模型会生成与当前 AGP/Kotlin/Gradle 不匹配的模板(例如过时的 plugin 写法、错误的 dependency 坐标)。缓解方式是:在提示中写清版本与约束,并要求它先读取项目现有 Gradle 文件再改;同时用 ./gradlew assembleDebug 作为硬门禁。
多文件联动遗漏:Android 功能常跨 Manifest/Gradle/资源/代码/测试,多数失败来自“少改一个文件”。缓解方式是:强制输出 git diff,并要求“文件树 + 变更清单 + 命令清单”,再用 Git checkpoints 保障回滚。
R8/反射相关运行时崩溃:R8 会做 tree shaking 与优化,反射/JNI 序列化模型常需要 keep rules;官方文档说明 R8 的工作方式并强调 release 应优化,但测试或库使用需谨慎;Guardsquare 也提醒 shrink/obfuscation 不是安全工具。 缓解方式是:让 Codex 在启用 shrink 后跑一遍 release 版本的关键路径(至少手工冒烟),并把 crash log 回灌生成 keep rules。
常见错误排障表(含修复建议)
| 现象/报错(关键词) | 常见原因 | 修复策略(优先顺序) |
|---|---|---|
Android Gradle plugin requires Java 17 to run |
使用了 AGP 8+ 或更高,但 Gradle 运行时 JDK 低于 17 | 1) 确认 JDK 17:Gradle/AGP 兼容要求。 2) 在 Android Studio 里把 Gradle JDK 指到 17(或统一到 embedded JDK 17)。 3) 命令行确保 JAVA_HOME/PATH 指向 JDK 17。 |
sdkmanager: command not found |
未安装 Android SDK Command-line Tools 或 PATH 未配置 | 1) 安装 cmdline-tools(可通过 Android Studio SDK Manager 或命令行安装 cmdline-tools;latest)。 2) 将 cmdline-tools/latest/bin 加入 PATH。 |
adb: command not found |
未安装 platform-tools 或 PATH 未配置 | 1) sdkmanager "platform-tools"。 2) PATH 加入 platform-tools;adb 是 Android SDK 工具。 |
adb devices 看不到真机 / unauthorized |
设备未开启 USB/Wi‑Fi 调试或未接受 RSA 授权 | 1) 按官方步骤开启开发者选项与 USB debugging / Wireless debugging。 2) 重新插拔并在设备端确认 RSA 弹窗。 |
| Emulator 极慢 / 无法加速 | 系统镜像架构与主机 CPU 不匹配,或加速条件不满足 | 1) Apple Silicon 使用 arm64-v8a 镜像(API 21+)以满足加速要求。 2) macOS 使用 Hypervisor.Framework;macOS 11 起不再支持 HAXM。 |
Execution failed for task :app:mergeDebugResources / 资源冲突 |
资源命名重复、依赖引入了同名资源 | 1) 让 Codex 输出冲突资源文件路径与依赖树(./gradlew :app:dependencies);2) 重命名资源或排除冲突依赖(工程策略,需结合项目)。 |
Duplicate class ... |
引入了重复依赖或不同版本同库 | 1) 要求 Codex 先读取版本目录(libs.versions.toml)并统一版本;2) 用 Gradle 依赖报告定位重复。 |
| Release 构建崩溃但 Debug 正常 | R8 shrink/obfuscation 移除了反射/序列化需要的类或方法 | 1) 确认 release 启用了 R8(Android 官方建议 release 优化)。 2) 为反射路径补 keep rules;并参考官方关于 keep rules/默认文件选择的建议。 |
debug.keystore 过期相关报错 |
debug 证书有效期到期(30 年) | 删除 ~/.android/debug.keystore 让 Android Studio/构建工具重新生成。 |
| GitHub Actions 构建慢 / 缓存无效 | 未使用合适的 Gradle Action 或缓存策略冲突 | 优先使用 gradle/actions/setup-gradle 配置 Gradle 与缓存;GitHub 官方教程也提到它负责 caching 并提供执行摘要。 |
| Codex 改动过大、难以审查 | 任务范围过宽、输出格式不受控 | 1) 强制输出 git diff + 小步提交;2) 使用 Git checkpoints(官方建议)。 3) 把任务拆成“仅 Gradle”“仅 UI”“仅测试”等子任务。 |
| API key 泄露风险 | 把 key 写进代码、提交到仓库、或贴进日志 | 遵循 OpenAI 官方建议:不要硬编码,使用环境变量/secret 管理,并监控 usage,必要时轮换 key。 |
附:一个“把 OpenAI API 用于生成补丁”的最小 curl 框架(供你写脚本/工具)
OpenAI 官方 code generation 指南给出通过 Responses API 调用模型生成代码的示例(含 https://api.openai.com/v1/responses、Authorization header、model 字段与 reasoning 选项)。
curl https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5.4",
"input": [
{"role":"system","content":"你是资深 Android/Kotlin 工程师。输出必须是 git diff + 命令列表。"},
{"role":"user","content":"请在当前仓库中实现:...(粘贴你的需求与约束)..."}
],
"reasoning": { "effort": "high" }
}'
将该输出接入“应用补丁 → ./gradlew assembleDebug/test → 失败回灌”的闭环,就是把 Codex 变成 Android 工程可持续生产力工具的关键。