【51信用卡】Android代码静态检查工具整理

android studio 相关说明 | 2018-08-25 00:33

作者介绍:

郑晓明,51信用卡客户端Android工程师

前蘑菇街客户端研发工程师,之前主要从事IM等项目开发。2017年加入51信用卡,目前主要负责51人品客户端项目开发,平时热衷于疑难问题排查及提高效率工具的开发。

随着51信用卡的业务功能不断迭代,项目中偶尔会出现一些不严谨的代码。如魔法数字,变量未判空,变量命名不符合规范等,这些都有可能引起App闪退问题。

但是这些在正常的CodeReview中很难发现,因此51信用卡用了Android的静态代码检查工具,还有自定义的Lint检查(自定义Lint这里先不介绍,后续会有文章介绍这个)。

Android的静态检查工具:

1.CheckStyles(代码格式和规范检查工具)2.FindBugs(检查字节码,即查找编译后的.class文件中的BUG,可以发现空指针问题)3.PMD(检查源码)4.Lint(Android Studio推荐的工具,发现BUG和优化的地方)

CheckStyles

检查Java源文件的代码格式和规范,可以使用默认,也可以自定义检查规则。51信用卡这边代码格式是按照Google官方推荐的。

检测范围

注解javadoc注释命名规范文件头导入包规范尺寸设置空格正则表达式修饰符代码块编码问题类设计问题重复、度量以及一些杂项

CheckSytle的安装可以通过Plugin进行安装CheckStyle-IDEA插件

具体使用可以自行百度。

51信用卡这边是根据gradle的配置运行的,如下:

关于checkstyles的检查规则文件,可以参照以下链接

gradle checkstyle配置:

github上的checkstyles:

执行gradle checkstyle命令之后会生成在/build/report/checkstyles下面

注意:这里的错误是变量命名方式不对,前面没有加上'm',if后面没有加空格

其他代码格式和规范检查工具

阿里推出的Java代码规范:

阿里巴巴Java开发手册终极版v1.3.0.pdf

Android开发规范:

在此基础上2017年10月14日杭州云栖大会推出了Idea插件:p3c插件

检查源码的代码漏洞

检测范围:

可能的bug:

空的try/catch/finally/switch块。无用代码(Dead code):无用的本地变量,方法参数和私有方法。空的if/while语句。过度复杂的表达式——不必要的if语句,本来可以用while循环但是却用了for循环。可优化的代码:浪费性能的String/StringBuffer的使用。

PMD的安装可以通过Plugin进行安装。CheckStyle-IDEA插件 :

具体使用可以自行百度。

这里的gradle配置:

执行 gradle pmd命令,

就会在/build/reports/pmd/生成

上图的问题

if(a == 1)    println "true"

这种格式需要加上大括号;还有无效引用需要去除;还有避免输出

e.printStackTrace();

FindBugs重点

检查bytecode的代码漏洞,即编译后的.class文件中的错误,可以查找出空指针等问题。

检测范围:

常见代码错误,序列化错误;可能导致错误的代码,如空指针引用;国际化相关问题:如错误的字符串转换;可能受到的恶意攻击,如访问权限修饰符的定义等;多线程的正确性:如多线程编程时常见的同步,线程调度问题;运行时性能问题:如由变量定义,方法调用导致的代码低效问题。

FindBugs可以通过Plugin搜索FindBugs-IDEA

具体看下控制台输出的错误级别:

技术手册:

更多请参见官网:

Gradle的配置如下

执行 gradle findbugs就可以

跟idea插件运行的是一致的。

Lint 是Android Studio 提供的代码扫描分析工具,它可以帮助我们发现代码结构/质量问题,同时提供一些解决方案,而且这个过程不需要我们手写测试用例。

检测范围:

Correctness:不够完美的编码,比如硬编码、使用过时 API 等。Performance:对性能有影响的编码,比如:静态引用,循环引用等。Internationalization:国际化,直接使用汉字,没有使用资源引用等。Security:不安全的编码,比如在 WebView 中允许使用   JavaScriptInterface等。

通过Lint是可以去除无用的资源的。

可以使用Android Studio内置的Lint,使用路径工具栏 -> Analyze -> Inspect Code…

或者配置gradle配置

执行完gradle lint可以在

/build/reports/lint/目录下

// Add findbugs, lint to the check task.// 执行'gradle check',可以运行lint,findbugs,pmd,生成/build/reports/目录下check.dependsOn

'checkstyle','findbugs','lint','pmd'

可以通过gradle check命令都执行下,集成了checkstyle,findbugs.lint,pmd。

前面4者之间的区别:

延伸点 Git Commit Hook检查:

自定义Lint

由于上述的检查工具只能对代码进行常规检查,后面51信用卡在此基础上增加了自定义Lint规则,主要是为了推进客户端部门的代码规范。规则具体如下:

1.Toast方法,建议使用基础组提供的Toast工具;2.Log,System.out.println,System.err.println打印,使用基础组提供的Log;3.检查New Messsage,提示使用Message.Obtain/handler.obtainMessage;4.检查HasMap<Integer,E>,

建议使用使用SparseArray替代HashMap<Integer,E>;5.检查图片尺寸,超过300KB,进行提醒压缩或重新设计;6.检查Java文件中是否存在中文硬编码;7.检查New Thread,建议使用基础组提供的TreadTool工具;8.TODO检查;9.Map.keySet使用,替换为entrySet;10.Manifest文件是否缺少Launch Activity;11.Intent putExtra中的key是否为写死,应设置为EXTRA_KEY_<name>;12.Catch异常是否有

NullPointer/IndexOutOfBounds;13.Activity是否直接继承与Activity/AppCompactActivity,应该为BaseActivity;14.枚举检查;

支持多语言的检查工具-Infer

支持的语言有Java、Objective-C、C和C++; 对Android和Java代码可以发现null pointer exceptions和resource leaks等;对iOS、C和C++代码可以发现memory leak等。

Infer实践:

,有空大家可以研究下。

参考资料

Android 代码优化工具:

github开源代码检查工具:

Infer实践:

Findbugs常见错误:

Findbugs是一个静态分析工具:

Git Commit Hook检查:

美团Lint实践:

Android Lint:自定义Lint调试与开发: