Android 自定义 Lint 实现静态代码扫描工具

文章目录关于静态代码扫描工具Lint的简单使用一、Lint 与 IDE 的结合使用二、Lint 与 gradle 命令的结合使用具体位置如下图:生成的HTML在浏览器打开如图:自定义 Lint为什么需要自定义 Lint?Lint 需要自定义检查的问题参考美团的方案针对 Lint 实施的思考开发自定义 Lint 前的准备工作Android SDK自定义 Lint 规则的流程**下面着重于如何编写自定...
摘要由CSDN通过智能技术生成

关于静态代码扫描工具

在我们项目迭代过程中,线上问题频繁发生。开发时很容易写出一些问题代码,例如 Serializable 的使用:实现了 Serializable 接口的类,如果其成员变量引用的对象没有实现 Serializable 接口,序列化时就会 Crash。再例如,如果 XML 资源文件包含未使用的命名空间,则不仅占用空间,还会导致不必要的处理。其他结构问题,例如使用目标 API 版本不支持的已弃用的元素或 API 调用等,可能导致代码无法正常运行。所以为了进一步减少问题发生,我们逐步完善了一些规范,包括制定代码规范,加强代码 Review,完善测试流程等。但这些措施仍然存在各种不足,包括代码规范难以实施,沟通成本高,因此其效果有限,相似问题仍然不时发生。

有没有办法从技术角度减少或减轻上述问题呢?

我们调研发现,静态代码检查是一个很好的思路。静态代码检查框架有很多种,例如 FindBugs、PMD、Coverity,主要用于检查 Java 源文件或 class 文件;再例如 Checkstyle,主要关注代码风格;但我们最终选择从 Lint 框架入手,因为它有诸多优势:

  • Lint 工具可检查 Android 项目源文件是否包含潜在错误,以及在正确性、安全性、性能、易用性、便利性和国际化方面是否需要优化改进。并且支持 class 文件、资源文件、Gradle 等文件的检查。

  • 扩展性强,支持开发自定义 Lint 规则

  • 配套工具完善,Android Studio、Android Gradle 插件原生支持Lint工具。

  • Lint 专为 Android 设计,原生提供了几百个实用的 Android 相关检查规则。

Lint的简单使用

一、Lint 与 IDE 的结合使用

点击 Analyze 的 Inspect Code 选项,即可开启 lint 检查,在Inspection窗口中可以看到lint检查的结果。并且 android 自带的lint规则的更改可以在 Setting 的 Edit 选项下选择 Inspections(File > Settings > Project Settings),对已有的 lint 规则进行自定义选择。

二、Lint 与 gradle 命令的结合使用

AS 的控制台,进入要使用 Lint 检查规则的模块目录,使用 gradle lint 命令。输出的结果会生成一个 xml 以及 HTML(可以在浏览器打开,页面非常简单直观)。路径信息也可以在控制台看到,比如我的就是:

Wrote HTML report to file:///D:/cccx_3.0/app/build/reports/lint-results.html
Wrote XML report to file:///D:/cccx_3.0/app/build/reports/lint-results.xml

具体位置如下图:

在这里插入图片描述

生成的HTML在浏览器打开如图:

在这里插入图片描述


自定义 Lint

为什么需要自定义 Lint?

由于每个业务线自身的需求,Lint 默认的检查项目可能不能满足我们的需求。 比如司机端一个自定义控件需要抽成一个库给其他项目使用,但是我们希望使用者必须在 XML 中定义一个属性,否则组件无法正常运行,我们希望Lint能够对此进行检查,并在忘记添加此属性时给出明确的错误提示。
再比如,我们的基础组件有一个日志库,能够方便的在 release 版本中关闭日志输出,还能够把日志输出到指定的文件中方便事后分析,这时如果来了一个新同学,他可能还是习惯性的用 android.util.Log 来打印日志,我们希望能够检测到本项目中所有使用了 android.util.Log 的代码,并发出警告。 要满足这些自定义需求,我们就需要通过 Android Lint 的扩展机制自己定制 Lint 规则。

Lint 需要自定义检查的问题

一、Crash 预防

Crash 率是我们司机端和乘客端的最重要的指标之一,我们期望使用 Lint 检查出一些潜在的 Crash,例如:

  • 原生的 NewApi,用于检查代码中是否调用了 Android 高版本才提供的 API。在低版本设备中调用高版本 API 会导致 Crash。
  • 实现了 Serializable 接口的类,如果其成员变量引用的对象没有实现 Serializable 接口,序列化时就会Crash。
  • 调用 Color.parseColor() 方法解析后台下发的颜色时,颜色字符串格式不正确会导致 IllegalArgumentException

二、Bug 预防

由于目前 Bug 数已经作为部门衡量的指标,我们也期望使用 Lint 来检车和预防,例如:

  • 所有的页面跳转使用统一的路由 UXRouter,并且 PATH 维护在统一的常量类里方便查阅和修改。
  • 使用 Fastjson 解析 JSON 数据时,用基础类型来接收的不要用get包装类型的方法。比如: getInteger()getIntValue()

三、性能/安全问题

对于司机端和乘客端来讲,性能和安全非常重要。我们期望使用Lint来检测一些可以规避的影响性能和安全的问题,例如:

  • 使用 PendingIntent 时,使用了空 Intent 会导致恶意用户劫持修改 Intent 的内容。所以使用 PendingIntent 时,禁止使用空 intent,同时禁止使用隐式 Intent。
  • 在 Android API level 8 以后增加了 android:allowBackup 属性值。默认情况下这个属性值为 true,故
    当 allowBackup 标志值为 true 时,即可通过 adb backup 和 adb restore 来备份和恢复应用程序数据。所以就需要强制将 android:allowbackup 属性设置为 false,防止 adb backup 导出数据。

四、代码编写规范

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值