Android自定义Lint实践

708 查看

概述

Android Lint是Google提供给Android开发者的静态代码检查工具。使用Lint对Android工程代码进行扫描和检查,可以发现代码潜在的问题,提醒程序员及早修正。

为保证代码质量,美团在开发流程中加入了代码检查,如果代码检测到问题,则无法合并到正式分支中,这些检查中就包括Lint。

为什么需要自定义

我们在实际使用Lint中遇到了以下问题:

  • 原生Lint无法满足我们团队特有的需求,例如:编码规范。
  • 原生Lint存在一些检测缺陷或者缺少一些我们认为有必要的检测。

基于上面的考虑,我们开始调研并开发自定义Lint。

自定义Lint入门

在介绍美团的实践之前,先用一个小例子,来看看如何进行自定义Lint。

示例介绍

开发中我们希望开发者使用RoboGuice的Ln替代Log/System.out.println。

Ln相比于Log有以下优势:

  • 对于正式发布包来说,debug和verbose的日志会自动不显示。
  • 拥有更多的有用信息,包括应用程序名字、日志的文件和行信息、时间戳、线程等。
  • 由于使用了可变参数,禁用后日志的性能比Log高。因为最冗长的日志往往都是debug或verbose日志,这可以稍微提高一些性能。
  • 可以覆盖日志的写入位置和格式。

这里我们以此为例,让Lint检查代码中Log/System.out.println的调用,提醒开发者使用Ln。

创建Java工程,配置Gradle

注:

  • lint-api: 官方给出的API,API并不是最终版,官方提醒随时有可能会更改API接口。
  • lint-checks:已有的检查。

创建Detector

Detector负责扫描代码,发现问题并报告。

可以看到这个Detector继承Detector类,然后实现Scanner接口。
自定义Detector可以实现一个或多个Scanner接口,选择实现哪种接口取决于你想要的扫描范围

  • Detector.XmlScanner
  • Detector.JavaScanner
  • Detector.ClassScanner
  • Detector.BinaryResourceScanner
  • Detector.ResourceFolderScanner
  • Detector.GradleScanner
  • Detector.OtherFileScanner

这里因为我们是要针对Java代码扫描,所以选择使用JavaScanner

代码中getApplicableNodeTypes方法决定了什么样的类型能够被检测到。这里我们想看Log以及println的方法调用,选取MethodInvocation。对应的,我们在createJavaVisitor创建一个ForwardingAstVisitor通过visitMethodInvocation方法来接收被检测到的Node。
可以看到get