最近开发了几款APP,深度使用了AI Agent工具开发软件,消耗了大概30亿token(大部分免费)后实践出的结果,作品已在GitHub上开源,点击即可查看成果。

事先说明,这是一期面向AI初学者的教程,进阶技巧需要自己大量实战演练

第一章 OpenCode CLI下载安装

首先安装node.js工具,安装链接

然后,在终端运行以下命令:

npm install -g @anomalyco/opencode

如果你是Linux/macOS用户,可直接运行以下命令:

curl -fsSL https://opencode.ai/install | bash

如果你是Windows用户,可以直接运行:

irm https://opencode.ai/install | bash

在安装好OpenCode CLI工具后,就可以正式开发了

第二章 Android Studio CLI安装

一行命令:

curl.exe -fsSL https://dl.google.com/android/cli/latest/windows_x86_64/install.cmd -o "%TEMP%\i.cmd" && "%TEMP%\i.cmd"

第三章 AGENTS.md生成

重点:AGENTS.md是AI Coding的灵魂,可以先在网页端和AI对话了解清楚需求后在最后让AI生成AGENTS.md文件,注意让AI不要在markdown代码块里生成就行(以便直接复制粘贴)

在AGENTS.md里,撰写清楚开发需要的技术栈,以及必要的约束条件(Android应用开发建议使用Kotlin+Jetpack Compose组件开发)

这里,把我自己踩过的坑分享一下:

Q:Agent在非UTF-8编码格式下编辑文件遇到乱码怎么办?
A:在AGENTS.md文件下明确说明禁止使用Powershell编辑或修改文件,或者使用chcp 65001命令让Powershell使用UTF-8编码,或者明确指定Python编码格式为UTF-8

Q:Agent在长会话下有时候会产生上下文冲突怎么办?
A:定期压缩上下文,使用/compose命令压缩上下文,一个通用的经验是上下文长度达到150k时就可以尝试压缩(限定256k上下文的情况下),如果上下文长度在1M(如DeepSeek-V4-Flash和DeepSeek-V4-Pro)也建议在300k时压缩上下文

Q:有时候Agent会在一个Task里卡死怎么办?(如在Gradle编译里卡死)
A:目前没有找到一个比较好的办法,但一个通用的办法是,在已经提示BUILD SUEESSFUL in x sBUILD FAILED in x s时,主动杀死对话,然后手动继续

这里给出一个通用的建议,就是一定要写出足够密集、详细的AGENTS.md文档,一份好的AGENTS.md是好产品的基础!

第四章 Android通用技术栈整理

这一部分由AI生成。

4.1 核心基础

  • 开发语言Kotlin(官方首选,空安全、协程支持)
  • 最低 API 级别:API 21(Android 5.0)或根据市场调整为 API 24+
  • 构建工具:Gradle(使用 Kotlin DSL)

4.2 UI 层

技术 选型与说明
UI 框架 Jetpack Compose(声明式 UI,替代 XML 布局)
主题与设计 Material 3(M3)+ 动态颜色(Android 12+)
导航 Jetpack Compose Navigation(类型安全传参,配合 kotlinx-serialization
图片加载 Coil(专为 Compose 优化,支持内存/磁盘缓存、SVG、GIF)
图表绘制 Vico Charts(Compose 友好,支持交互、组合图表)

4.3 架构模式(MVVM)

层级 组件 说明
View @Composable 函数 仅负责 UI 渲染和事件分发,不包含业务逻辑
ViewModel AndroidViewModel + SavedStateHandle 持有 UI 状态,处理用户事件,调用用例(UseCase)
Model Repository + DataSource 单一可信源,管理本地/远程数据
状态管理 mutableStateOf / StateFlow / SharedFlow Compose 自动重组订阅状态
依赖注入 Hilt(Dagger 变体)或 Koin Hilt 为官方推荐,编译时正确性

4.4 数据持久化与安全存储

技术 选型与说明
本地数据库 Room(SQLite 抽象层,支持编译时检查、协程 Flow)
数据库加密 SQLCipher(通过 Room 的 SupportSQLiteOpenHelper 集成)
加密方式 AES‑256‑GCM(认证加密,推荐替代 CBC)
Argon2id(密钥派生/密码哈希,抗 GPU 暴力破解)
密钥管理 Android Keystore System(硬件级保护,防止密钥提取)
安全存储 EncryptedSharedPreferences(小数据) + EncryptedDataStore(Proto/键值对)

集成示例

  • 用户输入主密码 → 用 Argon2id(高内存/迭代参数)派生加密密钥。
  • 该密钥存入 Android Keystore(需设置 setUserAuthenticationRequired)。
  • 将密钥传递给 SQLCipher,打开加密的 Room 数据库。
  • 敏感字段(如令牌)可用 AES‑256‑GCM 二次加密后存入库中。

4.5 异步与并发

技术 选型与说明
异步框架 Kotlin 协程(Coroutines) + Flow
作用域 viewModelScope(ViewModel 层)、lifecycleScope(UI 层)
数据流 StateFlow(替代 LiveData)+ SharedFlow(一次性事件)
复杂异步处理 Flow 操作符(.map.filter.flatMapConcat 等)

4.6 网络与后端交互(可选整合)

技术 选型与说明
HTTP 客户端 OkHttp(拦截器、连接池)
REST API Retrofit(支持协程 suspendFlow
序列化 kotlinx‑serialization(比 GSON 更安全,Compose Navigation 也用它)
证书固定 OkHttp CertificatePinner(防中间人攻击)

4.7 图表绘制(Vico 专述)

功能 Vico 实现
折线图/柱状图/饼图 CartesianChartPieChart
Compose 集成 直接使用 Chart 可组合项,支持 rememberChart
交互 缩放、平移、点击高亮、滚动联动
数据适配 通过 MappedCartesianChart 映射 Room 查询出的 List<...>
性能 基于 Canvas 绘制,适合滚动大屏数据

4.8 依赖注入模块化示例(Hilt)

// 安全模块
@Module
@InstallIn(SingletonComponent::class)
object SecurityModule {
    @Provides
    @Singleton
    fun provideArgon2id(): Argon2id = Argon2id(
        iterations = 3, memory = 65536, parallelism = 1
    )
    
    @Provides
    @Singleton
    fun provideAes256Gcm(): Aes256Gcm = Aes256Gcm()
}

// 数据库模块(集成 SQLCipher)
@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
    @Provides
    @Singleton
    fun provideEncryptedDatabase(
        @ApplicationContext context: Context,
        aes: Aes256Gcm
    ): AppDatabase {
        val passphrase = aes.deriveKeyFromKeystore()
        val factory = SupportSQLiteOpenHelper.Configuration
            .builder(context)
            .callback(RoomDatabase.Callback())
            .passphrase(passphrase.toByteArray())
            .build()
        return Room.databaseBuilder(...)
            .openHelperFactory(SupportFactory(factory))
            .build()
    }
}

4.9 测试策略

层级 工具
单元测试 JUnit4/5 + MockK(Mock 库)+ Turbine(Flow 测试)
UI 测试 Compose UI Testing(SemanticsMatcherComposeTestRule
数据库测试 Room in‑memory 数据库 + SQLCipher(测试专用密钥)
加密测试 使用已知答案测试(KAT)验证 Argon2id / AES 实现

4.10 补充推荐(提升工程质量)

  • 日志与崩溃上报:Timber + Firebase Crashlytics / Sentry
  • 代码质量:Detekt(静态分析)+ ktlint(格式化)
  • 内存监控:LeakCanary + 自定义 StateFlow 收集器监控
  • 构建变体:debug / release + staging(不同加密参数,避免生产密钥暴露)

4.11 总体架构总结

[View (Compose)] 
    ↕ (State/Event)
[ViewModel] —uses→ [UseCase/Interactor]
    ↕ (调用)
[Repository] (单一可信源)
    ├─ [Local: Room + SQLCipher] (加密存储)
    │     └─ [AES-256-GCM 字段级加密]
    └─ [Remote: Retrofit] (可选)
[安全管理器]
    ├─ [Argon2id] (密码哈希/派生)
    ├─ [Android Keystore] (主密钥)
    └─ [SQLCipher] (透明加密数据库)

这套技术栈平衡了安全性(军用级加密)、开发现代性(纯 Compose + Kotlin)和可维护性(MVVM + Hilt)。若应用对安全性要求非极端高,可直接将密钥派生后存入硬件加密区(Keystore),无需用户每次输入密码。

第五章 Debug和Release

Debug版本是开发者内部为了测试需要构建的内部版本,Release版本是开发者发布时对外公布的版本,以下是详细信息(AI生成):

5.1 Debug 与 Release 的基本区别

在 Android 开发中,构建类型(Build Type)通常至少包含 debugrelease 两种,它们的核心差异如下:

配置项 Debug 构建 Release 构建
android:debuggable true(可在设备上被调试) false(禁止调试)
minifyEnabled false(不混淆代码) true(启用 R8/ProGuard 混淆)
shrinkResources false true(移除未使用资源)
签名 默认 debug 签名(公开、弱) 自定义 release 签名(安全、私密)
日志输出 大量调试日志(如 Log.d() 生效) 通常禁用或仅保留错误级日志
性能优化 未优化(便于断点调试) 开启编译器优化(-O2 等)
崩溃报告 通常未集成或使用测试版渠道 集成正式版崩溃报告(如 Firebase)

开发者日常使用 ./gradlew assembleDebug 生成可调试的 APK,而发布到应用商店时必须使用 assembleRelease


5.2 app_debuggable = true 的风险与 Release 版本的发布必要性

⚠️ android:debuggable = true 的严重风险

  1. 任意调试与代码注入
    debuggable = true 时,任何拥有该 APK 的人都可使用 jdbAndroid StudioFrida 等工具附加到进程,执行断点、修改变量、绕过校验逻辑(如支付验证、会员状态)。

  2. 源码暴露风险
    反编译工具(如 jadx)可以轻易还原出几乎原始的 Java/Kotlin 代码。虽然混淆(ProGuard)也非绝对安全,但 debuggable 会强制禁用混淆,导致业务逻辑、加密密钥(如果硬编码)、API 端点完全暴露。

  3. 内存 dump 敏感信息
    调试器可触发 heap dump 或 thread dump,从中提取正在内存中的明文密码、令牌、会话凭证等。

  4. 绕过安全检查
    许多安全检测(如 root 检测、证书固定)在 debuggable = true 时会被自动跳过或被攻击者轻易绕过。

  5. 可被重打包
    攻击者可以用工具(如 apktool)解包 APK,修改 AndroidManifest.xml 中的 debuggable 属性为 false 并重新签名发布——然而原始代码已暴露,修改后仍可植入恶意代码。

真实案例:曾有开发者将 debuggable = true 的 APK 直接上传至应用商店,导致用户数据被竞品分析、会员权益被破解,最终应用被下架并面临法律索赔。

✅ Release 版本发布的必要性

  • 保护用户数据安全
    关闭调试能力(debuggable = false)可阻止绝大多数动态分析工具的直接接入,降低数据泄露风险。

  • 代码混淆与资源压缩
    Release 版本强制启用 R8/ProGuard,将类、方法、字段重命名为无意义名称,极大增加静态逆向分析难度。同时移除无用代码和资源,减小 APK 体积。

  • 签名验证与完整性保护
    Release 版本使用自有密钥签名,应用商店会校验签名一致性,防止被篡改后重新上传。同时可在代码中运行时验证签名(防二次打包)。

  • 正式崩溃报告与性能监控
    只有 Release 版本才应接入正式环境的崩溃分析工具(如 Firebase Crashlytics),避免调试版海量错误日志污染数据,也防止敏感调试信息上传至外部服务。

  • 遵守应用商店政策
    Google Play、华为应用市场等明确规定,不允许提交 debuggable = true 或使用调试签名的 APK。违反者将被直接拒绝或下架。

  • 用户信任与法律合规
    对金融、医疗、政府类应用,未发布安全的 Release 版本可能违反《网络安全法》《GDPR》等法规,导致法律责任。

📌 最佳实践建议

  • 构建流程强制分离
    在 CI/CD 流水线中明确区分 debugrelease 任务,禁止将 debug APK 自动上传至任何公开渠道或应用商店。

  • 启用调试检测
    在 Release 版本的启动代码中加入检测:

    if (BuildConfig.DEBUG) {
        // 如果是 debug 构建,直接崩溃或弹窗警告
        throw IllegalStateException("Do not run debug build in production")
    }
    
  • 使用签名校验
    在 Release 版本中校验自身签名是否与预期一致,若不一致立即退出(防止重打包)。

  • 敏感信息管理
    build.gradle 中利用 buildConfigField 为 debug 和 release 配置不同的 API 密钥、加密参数,避免将真实生产密钥泄漏在 debug 包中。

  • 发布前检查清单
    使用 apkanalyzer 或第三方工具扫描 APK,确认 android:debuggablefalse,并且 R8 已正确运行。

结论debuggable = true 是开发期的便利工具,但绝不可出现在任何对外发布的 APK 中。Release 版本的安全配置是应用上线的最低门槛,忽视它将把用户数据、业务逻辑和开发者声誉置于极度危险的境地。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐