赞
踩
Android Lint 是有 Android SDK 提供的一种静态代码检测工具,用于检测 Android 的代码质量。Android Lint 的源码集成在 Android SDK Tools 16 及更高的版本中,我们可以在项目目录下通过 ./gradlew lint 命令调用,也可以通过 Android Studio 的 【Analyze】->【Inspect Code】路径调用 Lint 检查。
Lint 是 Android 提供的一个强大的,用于静态扫描应用源码并找出其中的潜在问题的实用工具。lint 工具可以检查你的 Android 项目源文件是否有潜在的错误,以及在正确性、安全性、性能、易用性、无障碍性和国际化方面是否需要优化改进。
Lint 既可以用作命令行工具,也可以与 Eclipse 和 IntelliJ 集成在一起。它被设计成独立于 IDE 的工具,我们可以在 Android Studio 中非常方便的使用它。
Fatal严重致命的、Error错误、Warning警告、Information提示、Ignore忽略 不提示
实际测试Fatal、Error只是错误代码部分增加红色和下划线提示,不会报错和阻断编译。
- android {
- lintOptions {
- // true--关闭lint报告的分析进度
- quiet true
- // true--错误发生后停止gradle构建
- abortOnError false
- // true--只报告error
- ignoreWarnings true
- // true--忽略有错误的文件的全/绝对路径(默认是true)
- //absolutePaths true
- // true--检查所有问题点,包含其他默认关闭项
- checkAllWarnings true
- // true--所有warning当做error
- warningsAsErrors true
- // 关闭指定问题检查
- disable 'TypographyFractions', 'TypographyQuotes'
- // 打开指定问题检查
- enable 'RtlHardcoded', 'RtlCompat', 'RtlEnabled'
- // 仅检查指定问题
- check 'NewApi', 'InlinedApi'
- // true--error输出文件不包含源码行号
- noLines true
- // true--显示错误的所有发生位置,不截取
- showAll true
- // 回退lint设置(默认规则)
- lintConfig file("default-lint.xml")
- // true--生成txt格式报告(默认false)
- textReport true
- // 重定向输出;可以是文件或'stdout'
- textOutput 'stdout'
- // true--生成XML格式报告
- xmlReport false
- // 指定xml报告文档(默认lint-results.xml)
- xmlOutput file("lint-report.xml")
- // true--生成HTML报告(带问题解释,源码位置,等)
- htmlReport true
- // html报告可选路径(构建器默认是lint-results.html )
- htmlOutput file("lint-report.html")
- // true--所有正式版构建执行规则生成崩溃的lint检查,如果有崩溃问题将停止构建
- checkReleaseBuilds true
- // 在发布版本编译时检查(即使不包含lint目标),指定问题的规则生成崩溃
- fatal 'NewApi', 'InlineApi'
- // 指定问题的规则生成错误
- error 'Wakelock', 'TextViewEdits'
- // 指定问题的规则生成警告
- warning 'ResourceAsColor'
- // 忽略指定问题的规则(同关闭检查)
- ignore 'TypographyQuotes'
- }
- }
-

// 回退lint设置(默认规则)
lintConfig file("default-lint.xml")
default-lint.xml手动创建放在当前module目录
类似
这种可以单独写在xml中
分为三种:
第一种,常见的实时检测,AndroidStudio自带的,可以通过lintOption配置显示错误的等级。
测试 我把NewApi和InlineApi这种错误改成Fatal致命的,build同步一下
看代码
只会提示但不会阻挡编译和运行,Error的效果相同。
Warning和Infomational的效果一样,也是只会提示但不会阻挡编译和运行。
忽略检测
指定方法忽略
lint在实时检测只能发挥提示的作用,进一步查看lint规则,找到需要的规则。
下方有专门的规则列表
https://wiki.h3d.com.cn/pages/viewpage.action?pageId=86346982
针对空指针,手动写个报错代码
未赋值实时检测lint是有提示的。
手动赋值为null竟然不显示,下面会依次查找现有规则。
第二种,手动静态扫描
第三种,Gradle命令
这些命令,会执行gradle文件,应用lintOptions的配置,进行Lint检测,结果会放在配置中指定的xml或html中。
生成html报告中没有找到空指针相关的提示。
Lint规则
官方规则
Android Lint Checks - Android Studio Project Site
我翻译后的规则单独都放在了这里
https://wiki.h3d.com.cn/pages/viewpage.action?pageId=86346982lint规则包含一下几个分类
查找android官方lint库,没有找到类似空指针这种语法级别的规则。
由于每个业务线自身的需求,Lint 默认的检查项目可能不能满足我们的需求。 比如司机端一个自定义控件需要抽成一个库给其他项目使用,但是我们希望使用者必须在 XML 中定义一个属性,否则组件无法正常运行,我们希望Lint能够对此进行检查,并在忘记添加此属性时给出明确的错误提示。
再比如,我们的基础组件有一个日志库,能够方便的在 release 版本中关闭日志输出,还能够把日志输出到指定的文件中方便事后分析,这时如果来了一个新同学,他可能还是习惯性的用 android.util.Log 来打印日志,我们希望能够检测到本项目中所有使用了 android.util.Log 的代码,并发出警告。 要满足这些自定义需求,我们就需要通过 Android Lint 的扩展机制自己定制 Lint 规则。
同时发现潜在的空指针未赋值等造成Crash的语法问题。
如果要查看 lint 工具支持的 issue 的完整列表和它们所对应的 issue ID,可以使用 lint --list 命令。
Lint 中包括多种类型的 Scanner 如下,其中最常用的是扫描 Java 源文件和 XML 文件的 Scanner:
SourceCodeScanner:扫描 Java 和kotlin源文件
XmlScanner:扫描 XML 文件
ClassScanner:扫描 class 文件
BinaryResourceScanner:扫描二进制资源文件
ResourceFolderScanner:扫描资源文件夹
GradleScanner:扫描 Gradle 脚本
OtherFileScanner:扫描其他类型文件
使用Detecotor探测器,实现多个scanner扫描,然后找出lint问题,并通过Issue提示出来。
最后通过注册器IssueRegistry,注册到androidLint。
类型选Java or Kotlin library,命名lint_tools
包名com.h3d.qqx5.lint,保持现有结构
导包
compileOnly "com.android.tools.lint:lint-api:$lint_version"
compileOnly "com.android.tools.lint:lint-checks:$lint_version"
一定要是compileOnly确保只编译不打包进主Module。
我这里使用kotlin的module所以额外有kotlin导包。
继承Detector探测器,实现SourceCodeScanner接口,该接口支持扫描java和kotlin类。
看看源码该扫描类的方法
返回此检测器感兴趣的方法名称列表,或者空,也就是该类调用了什么方法,需要设置要检测的方法名,限制了范围。
方法访问,由getApplicableMethodNames()限制的方法名,该方法就可以检测到指定的方法。
比如检查App内调用了系统Log和System.out.println方法的标记并提示报错。
isMemberInClass是检查指定的方法的类名是否存在于该检测类中。存在我们就荣国ISSUE来跟Lint一样的样式提示出来。
参数分别是1、取消检测使用的注解名称 2和3、lint提示 4、Lint类型(性能、Icon、国际化这种,默认Lint)5、优先级1-10 6、报错等级 7、默认实现
编写好的ISSUE需要注册到Lint
由于安卓官方推荐的方式是把lint_tools打成jar,然后命名为lint.jar直接放到开发者C盘的.android/lint目录下使用,这将导致所有工程都要使用该lint,没必要。
lint_tools是lib工程只会生成jar,如果将该lint_tools直接导入主module,因为module是以jar的形式,无法直接发布,需要以aar形式引入。
这就需要中间module作为aar,创建Android Module (aar) lint_check
build.gradle下发布lint_tools module
其他选项和主module保持一致
主Module导入
gradle同步一下,以后build或者编译或者lint运行都可以实时检测。
但是空指针怎么判断还没有具体方法,继续研究~
改造LogDetetor,设想检测方法,所有get开头的方法判断获取到的内容是否为空
但是发现并没有错误提示。
后来查看api注释,只有添加的调用方法名,才能被Lint检查,Log之所以可以是因为它是系统Api,被广泛调用。也就是说已经被调用的通用代码可以使用,但是空指针一般都是未知的方法。
尝试加入
必须明文传入的方法才可以被检测,所以空指针的Lint暂时未找到实现方式。
设计思路:传入原始数据,返回不为空的数据
类型必须要使用到泛型,因为Java的泛型实例化也是必须使用class类型的,由于data如果为空是不可能拿到class的,所以还需要额外的class传入,泛型这里是class<T>
对一个可能的数据空,调用该方法,除非实例化异常,否则很难出空指针异常了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。