Android 静态代码分析

Android 静态代码分析

在一些大型项目中,静态代码分析是必不可少的,通过静态代码分析可以避免一些低级的问题,与此同时可以规范代码书写、提高代码质量。本文主要介绍4种分析工具(CheckStyle、Findbugs、PMD、Android Lint)和如何快速接入。


功能介绍

CheckStyle

CheckStyle 主要的功能就是实时检测,代码的规范(Code Style)是否符合我们规定的一个模板,如定义的静态常量是大写,
局部参数以m开头,函数名字不超过20个字等。当发现这些不符合这些规范时,它就报一个警告或者错误等提示。

CheckStyle 检验的主要内容包括Javadoc注释、命名约定、标题、Import 语句、体积大小、空白、修饰符、块、代码问题、类设计和混合检查。它的功能比较丰富,相对配置起来比较复杂,需要根据自己的需求配置想要检查的内容。在 Android 项目中使用了Android Studio它集成了 IDEA 的拓展特性,它也拥有 CheckStyle 的插件,在 Android 项目中,使用的 Gradle 配置。

Findbugs

Findbugs 主要的功能是使用静态分析来检测 java 字节码中发现的错误。所以它分析的是程序的字节码,它不仅可以检测出一些普遍的错误,也可以检测由于对语言特性误解而产生的错误。由于 FindBugs 分析代码字节码,所以至少需要编译一次代码才能够进行检查。

Findbugs 检验的主要内容包括找出 hash equals 不匹配、Null 指针对 null 的解引用(dereference)和冗余比较、初始化之前读取字段等问题。此外,用户还可以自己定义规则。在 Android Studio 中开发 Android 项目时利用 findbugs 插件可以找到潜在的很多问题,避免上线后才发现这些低级的问题,findbugs 插件可以为这些 bug 定义等级,发布到控制台,方便开发者逐一解决

PMD

PMD 主要的功能就是通过静态分析获知代码错误。也就是说,在不运行 Java 程序的情况下报告错误。它跟 Findbugs 类似,但是它不是检测字节码,它是直接检测源代码。

PMD 检验的主要内容包括潜在的bug:空的 try/catch/finally/switch 语句,未使用的代码:未使用的局部变量、参数、私有方法等,可选的代码:String/StringBuffer的滥用,复杂的表达式:不必须的if语句、可以使用 while 循环完成的 for 循环,重复的代码:拷贝/粘贴代码意味着拷贝/粘贴 bugs,循环体创建新对象:尽量不要再 for 或 while 循环体内实例化一个新对象,资源关闭:Connect,Result,Statement等使用之后确保关闭掉等问题。此外,用户还可以自己定义规则,检查Java代码是否符合某些特定的编码规范。同样在在 Android Studio 有 PMD 插件,利用 PMD 插件可以简单直观的发现 bug。

Android Lint

Android Lint主要的功能它可以检测Android项目源文件中潜在的bug,也可以在正确性、安全性、性能、可用性、可访问性和国际化等方面进行优化。Android Lint是一个静态的代码分析工具。

Android Lint检验的主要内容包括布局性能(以前是 layoutopt工具,可以解决无用布局、嵌套太多、布局太多)、未使用到资源、不一致的数组大小、国际化问题(硬编码)、图标的问题(重复的图标,错误的大小)、可用性问题(如不指定的文本字段的输入型)、manifest文件的错误等问题。在使用时需要在gradle文件中的进行配置。


快速接入

下载config.zip,解压后看下目录结构

下载链接:http://download.csdn.net/detail/u010420435/9806992

这里写图片描述

quality.gradle 文件主要定义了4种检查工具的 gradle task ,每个 task 则分别定义了检查规则、忽略条件以及检查路径、输出报告格式等内容。代码如下

//引入插件
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
apply plugin: 'pmd'

//将 checkstyle, findbugs, pmd 和 lint 加入到 gradle check task 中
check.dependsOn 'checkstyle', 'findbugs', 'pmd', 'lint'

task checkstyle(type: Checkstyle) {
    configFile file("${project.rootDir}/config/quality/checkstyle/square-picasso-checkstyle.xml")//指定规则
    configProperties.checkstyleSuppressionsPath =file("${project.rootDir}/config/quality/checkstyle/suppressions.xml").absolutePath
source 'src'
include '**/*.java'
exclude '**/gen/**'
classpath = files()}

task findbugs(type: FindBugs, dependsOn: assembleDebug) {
    ignoreFailures = false
    effort = "max"
    reportLevel = "high"
    excludeFilter = new File("${project.rootDir}/config/quality/findbugs/findbugs-filter.xml")//配置过滤文件
    classes = files("${project.rootDir}/你要测试的项目名/build/intermediates/classes")

    source 'src'
    include '**/*.java'
    exclude '**/gen/**'

    reports {
        xml.enabled = false
        html.enabled = true
        xml {
            destination "$project.buildDir/reports/findbugs/findbugs.xml"//配置report输出路径
        }
        html {
            destination "$project.buildDir/reports/findbugs/findbugs.html"//配置report输出路径
        }
    }

    classpath = files()
}

task pmd(type: Pmd) {
    ignoreFailures = false
    ruleSetFiles = files("${project.rootDir}/config/quality/pmd/pmd-ruleset.xml")
    ruleSets = []

    source 'src'
    include '**/*.java'
    exclude '**/gen/**'

    reports {
        xml.enabled = false
        html.enabled = true
        xml {
            destination "$project.buildDir/reports/pmd/pmd.xml"
        }
        html {
            destination "$project.buildDir/reports/pmd/pmd.html"
        }
    }
}

android {
    lintOptions {
        abortOnError true
        xmlReport false
        htmlReport true
        lintConfig file("${project.rootDir}/config/quality/lint/lint.xml")
        htmlOutput file("$project.buildDir/reports/lint/lint-result.html")
        xmlOutput file("$project.buildDir/reports/lint/lint-result.xml")
    }
}

checkstyle.xml 文件定义了checkstyle 的检查规则,suppressions.xml定义了忽略条件

findbugs-filter.xml 文件定义了过滤规则

lint.xml 文件定义了Android lint 的规则

pmd-ruleset.xml 文件定义了pmd 的检查规则集

将解压后的 config 文件夹放到 Android Studio 项目的根目录,然后在你要进行静态代码分析的项目中gradle文件加入如下代码

apply from: '../config/quality.gradle'

至此,引入过程已经结束。


开始执行

执行方式有两种

1.直接执行更目录 gradle check task ,执行这个 task 可以一次性把4种检查全部执行一遍

2.分布执行

在测试项目的 gradle task 找到 checksytle、pmd、findbugs 的 task 双击执行即可如下图
这里写图片描述

执行结束后测试报告会在你项目的 /build/reports 目录下生成

参考链接:http://blog.csdn.net/hp910315/article/details/48809935

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值