Android Lint 基础:检查类型、内置规则与命令行运行
说到 Android Lint,我觉得它就像是项目里的一个「静态代码巡查员」。你写代码的时候,它不会说话,但等你一运行检查,它就能把潜藏的问题一个个揪出来。性能隐患、安全漏洞、甚至拼写错误——它都能管。我个人习惯在每次提交代码前跑一遍 Lint,效果比人工 review 要稳定得多。
Lint 检查类型
Android Lint 把检查分了 6 大类。为什么要这么分?因为不同问题的影响面不一样,你修复的时候优先级也不同。我过去在项目中遇到过把「性能」问题当成小 bug 忽略,结果上线后卡顿反馈直接爆了。所以分类是有意义的。
| 检查类型 | 说明 | 我比较关注的点 |
|---|---|---|
| Correctness(正确性) | 代码逻辑、API 误用、资源缺失等 | 这是最高优先级,我会在 CI 门禁里设成 error |
| Performance(性能) | 内存泄漏、布局过度绘制、冗余对象创建 | 很多新人不注意 StringBuilder 拼接,跑一次 Lint 就暴露了 |
| Security(安全) | WebView 设置、明文通信、导出组件 | 以前我踩过 WebView 允许 file 协议的坑,后来就加了这条规则 |
| Usability(可用性) | TextView 缺失 contentDescription、控件点击区域过小 | 无障碍设计其实不难,但很容易被忽略 |
| Accessibility(无障碍) | 与 Usability 类似,但更侧重辅助功能 | 其实很多团队把这俩合并了,但 Lint 是分开的 |
| Internationalization(国际化) | 硬编码字符串、缺失翻译、排版方向问题 | 你想想看,如果你的 app 要出海,这条很重要 |
内置规则概览
Android Lint 内置了 300+ 条规则。你不需要全部记住,但有几类是我每次必查的:
- Nullability 相关:
NullArgument、Nullable标注检查。我曾经被一个 nullable 返回值坑到崩溃,现在 Lint 直接帮我拦住。 - 布局性能:
NestedWeights、UselessParent、Overdraw。说白了就是减少层级、减少重绘。 - 资源冗余:
UnusedResources、UnusedIds。项目大了之后,残留的资源会塞爆 APK。 - 线程安全:
HandlerLeak、ObsoleteSdkInt。Handler 导致的内存泄漏,你肯定见过。 - Gradle 相关:
GradleDependency、GradleCompatible。建议把 gradle 版本检查也加到 Lint 里。
这些规则默认是开启的,你可以在 lint.xml 里调整严重级别。嗯,这里要注意:不要把错误改得太宽松,否则 Lint 就形同虚设了。
命令行运行方式
我平时最常用命令行跑 Lint,因为便于集成到 CI 流水线。有三种方式:
方式一:通过 Gradle 任务
./gradlew lint # 所有 build variant 都检查
./gradlew lintDebug # 只检查 debug 变体
./gradlew lintRelease # 通常 release 变体要求更严格
结果会生成 HTML 和 XML 报告,默认在 build/reports/lint-results.html。
方式二:直接调用 lint 命令行工具
lint --check "Correctness,Performance" --report ./lint-report.html ./app/src/main
这个适合你做自定义扫描,比如只检查某个模块。我个人习惯在 shell 脚本里封装一下,把参数写清楚。
方式三:结合 Gradle 的 LintOptions 配置
android {
lintOptions {
abortOnError true // 发现错误就停止构建
xmlReport false
htmlReport true
htmlOutput file("lint-report.html")
checkReleaseBuilds true
// 我曾经把某个规则设成 "ignore",结果上线出事了
disable 'MissingTranslation'
enable 'RtlHardcoded'
}
}
避坑提醒:我曾在项目中把 abortOnError 设为 false,结果 CI 虽然通过了,但 Lint 错误被掩盖。后来发现线上 app 有 NullPointerException,查下来就是 Lint 报过的。所以建议正式构建一定要 abortOnError true。
另外,你可以用 ./gradlew lintVitalRelease 只检查 release 变体里的致命问题,速度会快很多。
使用频率最高的几个命令行参数
| 参数 | 作用 |
|---|---|
--check |
指定要运行的检查类型,比如 --check "Correctness" |
--disable |
临时禁用某条规则,我用它来屏蔽已知的假阳性 |
--enable |
启用某条规则,比如你需要特别关注国际化时 |
--report |
自定义报告输出路径 |
--quiet |
只输出错误,不输出警告信息,适合 CI 日志 |
一点经验:当你第一次在项目里跑全量 Lint,可能会看到几百个警告。不要慌。先修 error,再把 warning 按类型分批修。我一般分三天:第一天修正确性和安全,第二天修性能,第三天扫尾巴。这样团队压力小,效果反而好。
小技巧:如果你嫌 Lint 报告太长,可以用 --baseline 参数。先跑一次生成 baseline.xml,之后 Lint 只会报告新增的问题。这个在大型遗留项目里特别好用,我们团队靠它慢慢把旧债还清。
最后,记得查看 $ANDROID_HOME/tools/bin/lint 的完整文档。你可以在终端里输入 lint --help 得到所有参数列表。对于刚接触 Lint 的团队,我建议从 ./gradlew lintDebug 开始,只看 debug 变体,等稳定后再开启全部变体。