SuperAPI AI 工具集

software-android-native

编程与开发

查看项目

更新于 10-16 04:06

技能介绍

用途

该技能仅用于原生 Android 开发。它是 Compose 优先 Android 应用的默认共享技能入口,面向 API 28+ 目标、从旧代码库进行的有界重写,以及在 Android Studio、Codex 和 Claude Code 中的智能体辅助工作流。

适用场景包括:为 API 28+ 的 Android 应用构建新的 Compose 优先界面与功能;规划并执行从 Views 或较旧 Kotlin/Java 代码库的有界重写;在 Android Studio、Codex 或 Claude Code 中搭建智能体辅助的 Android 工作流;实现 Kotlin Coroutines、Flow 与 ViewModel 状态模式;准备数据安全声明、目标 SDK 合规与发布门禁;审查原生 Android 代码的架构、性能与合规性。

主要能力与默认选型

状态与 UI:新界面默认使用 Jetpack Compose,仅在现有成熟流程或第三方 SDK 需要时使用 Views 互操作;可观察状态使用 ViewModel + StateFlow(Kotlin 2.x),替代新代码中的 LiveData。

异步:使用 Kotlin Coroutines + Flow;阻塞操作使用 Dispatchers.IO,CPU 密集型使用 Dispatchers.Default;优先结构化并发。

测试:单元/集成测试默认 JUnit 4 + Turbine(JUnit 5 需要经过验证的社区集成);UI 测试使用 Compose Testing API(ComposeTestRule),Espresso 仅用于 Views 互操作或旧界面。

状态机纪律:提交守卫使用 if (_uiState.value is Loading) return 防止 ViewModel 中双击重复提交;瞬时完成使用一次性 UI 效果或显式确认,不要用任意定时器重置持久状态;移除不可能再发生的密封类状态,避免死分支。

网络与韧性:使用 ConnectivityManager + NetworkCallback 包装为 StateFlow,发布 isConnected,离线时禁用提交按钮,并通过 collectAsStateWithLifecycle 观察。

依赖注入与架构:依赖注入使用 Hilt(@HiltViewModel、@Inject constructor、@Module + @InstallIn);本地持久化使用 Room + KSP,优先 @Upsert 而非分开的 insert/update,KSP 替代 KAPT;后台工作使用 WorkManager + CoroutineWorker,处理可延迟、约束感知的后台任务。

构建系统:优先 Gradle KTS(build.gradle.kts)配合版本目录(libs.versions.toml)。导航:优先类型安全的 Compose Navigation(2.8 起支持类型安全路由),使用 @Serializable 路由类;可评估 Navigation 3(稳定版)用于基于场景的自适应布局。

发布门禁:目标 SDK 合规、数据安全声明、ProGuard/R8 规则、Play Integrity、无障碍与真机验证视为非可选。

使用方式

执行流程:确认应用形态(Compose、Views 互操作、服务或发布门禁)→ 验证 Gradle、模拟器/设备、安装与启动的真实性 → 选择架构(ViewModel、StateFlow、Hilt、Room、Navigation)→ 实现带生命周期感知状态与测试的有界切片 → 检查 Kotlin、Compose、R8、计费与 Play 政策陷阱 → 构建、安装、启动、检查日志并报告证据。

运行时工具选择与设备验证:在实现前使用 software-android-runtime-debugging 的工具检查;构建循环细节见 Android Studio 工作流。

重写工作流:锁定基线(现有应用行为、最低 API 级别、设备类别、外部集成与非目标);选择目标默认值(Compose 优先、API 28+、ViewModel + StateFlow、Hilt、Room + KSP、Kotlin Coroutines、JUnit 4 或经验证的 JUnit 5 集成、Compose Testing);将重写切分为有界的垂直功能(应用外壳、认证/会话、核心导航、功能流程、集成、发布面);若使用多模块 Gradle,在添加新模块前验证模块依赖与构建顺序;从 Java 迁移到 Kotlin 时逐文件转换并审查惯用法,不要批量转换整个包;从 Views 迁移到 Compose 时在现有 XML 布局中使用 ComposeView 作为桥梁,不要一次性重写整个 Activity/Fragment 层级;每个切片要求证据(构建成功、安装与启动成功、针对性测试、对等说明、已知缺口);全程保持发布相关事项可见;每批结束时交接(变更行为、已执行验证、残余风险、下一切片)。

已知 Kotlin 陷阱

非原子状态写入导致丢失更新:MutableStateFlow.value 赋值本身线程安全,真正危险的是并发写入者下的非原子读-改-写(value = value.copy())静默丢弃更新。修复:保持 withContext(Dispatchers.IO) { ... } 块纯净(返回值,不在内部修改状态),并发更新使用 MutableStateFlow.update { },按约定将 Compose 快照状态(mutableStateOf)写入保留在主线程,并通过 collectAsStateWithLifecycle() 收集 UI 状态。

Strong Skipping 模式身份检查:自 2.0.20 起默认启用,不稳定参数按身份比较,稳定参数按相等性比较。在拆分状态或采用不可变集合前,检查编译器稳定性与实际重组。

LazyListScope lambda 边界:item 内容是 composable 并接受 Strong Skipping 记忆化;在非 composable DSL 块中分配的 lambda 是另一种情况,应在外层 composable 中创建所需的 remembered 回调。

Kotlin 2.x 上 Compose 插件版本偏差:自 Kotlin 2.0 起 Compose 编译器随 Kotlin 编译器发布,通过 Gradle 插件 kotlin("plugin.compose") 应用。插件声明过期或缺失会表现为类型不匹配错误。修复:在 libs.versions.toml 中将 plugin.compose 锁定到确切的 Kotlin 版本。

Compose 运行时回归:若在 LookaheadScope 下可暂停组合崩溃、嵌套 Popup 相对屏幕而非父级定位、或 SnapshotStateObserver 重入修改崩溃,先升级到最新 Compose UI 补丁版本,再视为应用层问题。

kotlinx-serialization + R8:库自带保留规则;命名伴生对象需要额外的模式特定规则;使用上游 Android 指南,检查合并规则,并对压缩发布路径做冒烟测试。

Kotlin 反模式

新代码中拒绝:K1 GlobalScope.launch;K2 向 launch 传递外部 Job;K3 在新 Compose 代码中使用 LiveData + observeAsState;K4 用可空性作为加载/错误/成功模型;K5 在 Kotlin 2.x 上保留 kapt(迁移到 KSP2);K6 将 StateFlow.value = copy(...) 视为无代价;K7 在 composable 体内过滤或排序列表;K8 在生产路径中使用 runBlocking。

架构判断

状态与效果归属:持久屏幕事实保留在 StateFlow 中(输入、加载、结果、可恢复错误、重建后所需数据);一次性导航、snackbar、焦点与触觉工作建模为具有命名交付策略的效果。为每个异步意图分配请求身份或取消先前任务,忽略被取代请求的结果,并在可能重复交付时使后端操作幂等。

Compose vs Views:Compose 是新屏幕的仓库默认;仅在集成约束合理时选择 Views 或互操作,例如第三方 SDK 提供无 Compose 包装的 View 渲染面、迁移中的旧屏幕、或 SurfaceView/TextureView 支持的连续渲染。

Hilt vs Koin:Hilt 是新 API 28+ 应用的仓库默认;仅在团队明确希望避免注解处理与 Gradle 插件开销、项目小到编译期图验证不如迭代速度重要、或代码库是 Hilt 无法运行的 Kotlin Multiplatform 模块时优先 Koin。

Kotlin Multiplatform(KMP):是跨 Android 与 iOS 共享业务逻辑的真实选项,但属于产品/架构决策,不是本技能的默认;若问题是“是否与 iOS 共享代码”,应路由到 software-mobile 做跨平台权衡。

何时不走原生:若实际问题是“该功能是否应为原生 Android 屏幕”,该决策属于 software-mobile,不应由本技能的 Compose 优先默认值静默回答。

Coroutines vs Flow 失败模式:suspend fun 返回单值,不适合多次发射的场景;将一次性操作包装为 Flow 会增加取消/背压机制而无收益。经验法则:现在一个值 → suspend fun;随时间零到多值 → Flow;不应重放的单一 ViewModel 到 UI 事件流 → SharedFlow 且 replay = 0。

进程死亡与 SavedStateHandle:ViewModel 在配置变更后存活,但在内存压力下进程死亡后不存活。用户不愿在后台杀死并恢复时丢失的内容必须通过 SavedStateHandle,而不仅是 ViewModel 字段状态。用 adb shell am kill <package> 在后台时测试,而不仅是旋转。

ANR 与帧预算

使用规范的运行时调试阈值对 ANR 分类,区分前台服务提升异常与 ANR。将帧预算重新推导为 1000 ms / 实测刷新率,并在受影响设备上验证。

运行时真相与提示

采用证据优先的执行循环:先验证工具现实(Android Studio Gemini、Gradle CLI、ADB、模拟器或设备可用性);在 UI 诊断前证明构建、安装与启动;保持仓库记忆精简且仅含事实;要求带明确证据产物的有界切片。

限制

该技能仅用于原生 Android 工作,不回答平台选择问题(是否应使用跨平台框架、WebView 或 KMP 共享模块),此类决策属于 software-mobile。KMP 共享代码的跨平台权衡不在本技能范围内。JUnit 5 需要经过验证的社区集成。具体版本相关声明需在引用前对照链接的发布说明重新验证。