Logo
热心市民王先生

需求拆解

需求分析 沙盒环境 Jetpack Compose

深入分析沙盒环境约束条件,定义最小可行的 lint 工作流

用户目标

用户的核心诉求可归纳为:在沙盒环境中建立一个「零编译产出的 Kotlin 代码质量门禁」,支持 Jetpack Compose 框架的专项检测。

目标工作流

flowchart LR
    A[编写代码] --> B{Lint 检查}
    B -->|发现错误| C[修复代码]
    C --> B
    B -->|全部通过| D[提交代码]
    
    style A fill:#e3f2fd
    style D fill:#c8e6c9
    style B fill:#fff3e0

这个循环需要满足三个硬性指标:

  1. 即时反馈:从保存文件到获得结果 < 3 秒
  2. 零编译依赖:不生成 APK/DEX/AAR 等任何构建产物
  3. Compose 感知:能够检测 Compose 特有的代码模式(如 remember、SideEffect 等)

约束条件量化

约束维度沙盒限制传统 Android Studio 环境差距分析
内存上限512MB - 2GB8GB - 16GB需降低 8-30 倍
磁盘空间1GB - 5GB20GB+(含 SDK)需精简 80%+
网络访问受限或离线完整访问无法动态下载依赖
启动时间< 5 秒30-60 秒(Gradle Sync)需提速 6-12 倍
持久化容器重启后重置持久化缓存需预置工具链

关键路径识别

要实现目标工作流,必须突破以下技术障碍:

障碍 1:Android Lint 的 Gradle 耦合

问题本质:Android Lint 并非设计为独立工具,其核心依赖 Android Gradle Plugin (AGP) 提供的 LintModel 和项目结构元数据。

证据数据

  • 直接调用 lint CLI 在 Gradle 项目上会报错:
    "myModule" is a Gradle project. To correctly analyze Gradle projects, 
    you should run "gradlew :lint" instead.
  • Android Lint 需要解析 build.gradle 文件获取依赖树、资源路径等元信息

影响评估

  • 严重阻塞:无法直接在沙盒中使用标准 Android Lint
  • 替代需求:寻找不依赖 AGP 的静态分析方案

障碍 2:Jetpack Compose 的语义分析

问题本质:Compose 不是普通 Kotlin 库,其使用模式依赖 Kotlin 编译器插件生成的特殊 IR(Intermediate Representation)。

典型 Compose 模式

// 需要检测的 Compose 特定模式
@Composable
fun MyScreen() {
    // ❌ 错误:在 Composition 中直接调用非 @Composable 函数
    val data = fetchData() 
    
    // ✅ 正确:使用 remember 缓存计算结果
    val cachedData = remember { fetchData() }
    
    // ❌ 错误:MutableState 赋值未使用委托
    var count = mutableStateOf(0)
    count.value++ // 正确,但 count++ 不会触发重组
}

现有工具支持度分析

检测项ktlintDetektAndroid Lint可行性
代码风格(缩进、命名)✅ 完整✅ 完整✅ 完整
复杂度(圈复杂度)❌ 不支持✅ 内置⚠️ 有限
@Composable 标注检查❌ 不支持⚠️ 需自定义✅ 内置
remember 使用模式❌ 不支持⚠️ 需插件✅ 内置
State 委托规范❌ 不支持❌ 不支持✅ 内置

障碍 3:类型解析的依赖困境

问题本质:高级静态分析(如空安全检测、API 弃用检查)需要类型解析(Type Resolution),这要求访问项目依赖的类路径(Classpath)。

依赖规模实测

  • 最小 Jetpack Compose 项目(单模块,基础依赖):
    • Gradle 下载量:~150MB
    • 解析后的 Classpath:~80MB
    • 依赖项数量:~200 个

沙盒困境

  • 无法预先下载所有可能的依赖组合
  • 离线环境下无法解析 Maven/Gradle 依赖

最小可行方案定义

基于上述障碍分析,定义沙盒环境的最小可行产品(MVP):

必须满足(Must Have)

  1. 纯源码级检查:不依赖编译产物或完整 Classpath
  2. 亚秒级响应:单文件分析时间 < 1 秒
  3. Compose 基础规则:覆盖最常见的 10 种 Compose 反模式
  4. 自动修复能力:80% 以上的风格问题可一键修复

应该支持(Should Have)

  1. 增量分析:仅检查变更文件,全项目扫描可在 5 秒内完成
  2. CI/CD 集成:支持 SARIF 标准输出格式
  3. 自定义规则:团队可扩展私有检查规则

可以延后(Could Have)

  1. 完整类型解析:需要依赖预下载或网络代理
  2. Android Lint 全规则:仅在资源允许时启用
  3. 实时 IDE 集成:通过 LSP 协议提供即时反馈

成功指标

定量指标

指标目标值测量方法
分析延迟(冷启动)< 3 秒从 CLI 调用到结果输出的时间
分析延迟(热启动)< 0.5 秒重复分析同一代码的耗时
内存占用峰值< 512MBdocker stats 监控
规则覆盖率> 70%与 Android Studio 默认规则的对比
误报率< 5%人工抽样检查结果

定性指标

  1. 开发者体验:lint 反馈的准确性、可读性、可操作性
  2. 集成复杂度:从现有 Android Studio 工作流迁移的难度
  3. 维护成本:规则更新、工具升级的投入工作量

技术选型约束

硬性排除项

以下方案因不满足沙盒约束而被排除:

  1. 完整 Gradle 构建:内存占用过高(>2GB),启动时间过长(>15s)
  2. Android Studio 远程模式:依赖 GUI 组件,无法在 headless 沙盒运行
  3. Kotlin Compiler Daemon:虽可复用进程,但仍需完整 Classpath

候选方案初筛

方案原理优势劣势沙盒适配性
ktlint CLIKotlin AST 解析单二进制、零依赖、极速无类型解析、规则有限⭐⭐⭐⭐⭐
Detekt CLIKotlin PSI + 规则引擎规则丰富、可扩展需 JVM、内存占用中等⭐⭐⭐⭐
QodanaJetBrains 代码分析云规则全面需网络、付费、非沙盒
SonarQube多语言分析平台生态成熟需服务端、资源占用高⭐⭐

本章节定义了沙盒 lint 方案的需求基线,后续章节将基于这些约束进行工具能力验证和方案设计。