前言
在开发应用的过程中,往往更关注功能和用户体验。其实优化代码,可以预防和减少一些可能会报出的问题。首先我们必须承认是人都会犯错,使用一些工具可以检查,然后修改问题。
1.lint
看下官方对lint的定义,如下图
lint的原理如下
使用lint,可有很多方式,包括下面但不只:
- 命令行
- gradle
- AS的Inspect Code
lint和proguard一样,可以写自定义过滤检查,有如下方式:
- Android项目根目录下的lint.xml
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<!-- Disable the given check in this project -->
<issue id="IconMissingDensityFolder" severity="ignore" />
<!-- Ignore the ObsoleteLayoutParam issue in the specified files -->
<issue id="ObsoleteLayoutParam">
<ignore path="res/layout/activation.xml" />
<ignore path="res/layout-xlarge/activation.xml" />
</issue>
<!-- Ignore the UselessLeaf issue in the specified file -->
<issue id="UselessLeaf">
<ignore path="res/layout/main.xml" />
</issue>
<!-- Change the severity of hardcoded strings to "error" -->
<issue id="HardcodedText" severity="error" />
</lint>
- 禁止Java文件检查
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
- 禁止xml文件检查
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="UnusedResources" >
<TextView
android:text="@string/auto_update_prompt" />
</LinearLayout>
更多关于lint可以查阅:write lint
2.checkstyle
checkstyle帮助开发者实现常用JAVA代码规范的自动化检查。它的功能比较丰富,相对配置起来比较复杂,你需要根据自己的需求配置你想检查的东西,比如Annotations,Block Checks,Class Design,Coding,Duplicate Code,Headers,Imports,Javadoc Comments,Metrics,Miscellaneous,Modifiers,Naming Conventions,Regexp,Size Violations,Whitespace。
我参考glide写了下自己的配置文件,在project根目录下的build.gradle
添加如下代码
subprojects { project ->
apply plugin: 'checkstyle'
checkstyle {
toolVersion = '6.12.1'
}
checkstyle {
configFile = rootProject.file('huaweicheckstyle.xml')
configProperties.checkStyleConfigDir = rootProject.rootDir
}
task('checkstyle', type: Checkstyle) {
source 'src'
ignoreFailures false
showViolations true
include '**/*.java'
exclude '**/gen/**'
classpath = files()
}
afterEvaluate {
if(project.tasks.findByName('check')) {
check.dependsOn('checkstyle')
}
}
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
}
}
}
可以对整个project执行checkstyle
gradlew.bat checkstyle
也可以对某个module执行checkstyle,比如app模块
另外可以安装下checkstyle-idea插件,在settings添加自己的checkstyle配置文件。
可以在窗口中执行对应的操作
当然你可以扫描单个java文件
3.FindBugs
findbugs是一个分析bytecode并找出其中可疑部分的一个工具。它给项目字节码做一个全面扫描,通过一些通用规则去判断可能潜在的一些问题,比如性能,多线程安全等等。有些时候它也会给出很详细的说明,为什么这种做法不大好,蛮有意思的。
找到需要集成的android项目,一般是app模块,在其的build.gradle添加如下代码集成:
apply plugin: 'findbugs'
findbugs {
toolVersion = FINDBUGS_VERSION
}
afterEvaluate{
task('findbugs', type: FindBugs, dependsOn: assembleDebug) {
description 'Run Findbugs'
group 'verification'
classes = fileTree('build/intermediates/classes/')
source fileTree('src')
classpath = project.configurations.compile
effort 'max'
excludeFilter file("findbugs-exclude.xml")
reports {
xml.enabled = false
html.enabled = true
}
}
check.dependsOn('findbugs')
}
FindBugs也可以自定义过滤检查,在上面代码中,我们已经使用了findbugs-exclude.xml作为自定义过滤检查,简单的配置如下:
<FindBugsFilter>
<Match>
<Class name="~.*R\$.*"/>
</Match>
<Match>
<Class name="~.*Manifest\$.*"/>
</Match>
</FindBugsFilter>
关于更详细的文档可以查看:findbugs
经过上面的配置之后,可以在右边的gradle窗口里找到对应的task,如下图
点击运行之后,就可以在app/build目录下面找到对应的错误报表
打开这个html文件,找到需要修改的问题。
4.pmd
PMD也是一个静态代码分析工具,它主要用来分析一些常见问题。
PMD和Findbugs功能上有很多重叠的地方,二者区别主要体现在分析对象上,Findbugs扫描的是字节码,所以找到问题的级别有可能不一样,它有很多定义好的rule,例如在Android里,目前有三项规则:
- CallSuperFirst,它会检查在Activity或Service里的子类里,是否在错误位轩调用父类onCreate等应该放在方法前的方法。
- CallSuperLast,和CallSuperFirst,但它会检查一些应该在方法结束时才调用父类实现的情况。
- DoNotHardCodeSDCard,这也是一个常见错误,你应该用Environment.getExternalStorageDirectory()
目前为止PMD对于Android的检查项并不多,使用它主要是用来检查一些JAVA中的常见错误。
配置如下:
apply plugin: 'pmd'
pmd {
toolVersion '5.4.0'
}
afterEvulate {
task('pmd', type: Pmd) {
targetJdk TargetJdk.VERSION_1_7
description 'Run pmd'
group 'verification'
ruleSets = []
ruleSetFiles = files('pmd-ruleset.xml')
source = fileTree('src')
reports {
xml.enabled = false
html.enabled = true
}
check.dependsOn('pmd')
}
}
pmd也可以配置过滤检查文件,如上我们使用了pmd-ruleset.xml
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ruleset name="PMD.rul" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>This ruleset was created from PMD.rul</description>
<rule ref="rulesets/java/basic.xml">
<exclude name="AvoidBranchingStatementAsLastInLoop"/>
</rule>
</ruleset>
更多配置可以查阅:pmd
和FindBugs一样,可以在右边的gradle窗口里找到pmd task
点击运行之后,可以在app/build目录下面找到对应的报表文件。
打开这个pmd.html,针对性修改存在的问题。
总结
有效的使用上面几个工具,可以极大的提高我们的代码质量,也能规避很多不好代码带来的潜在问题。
后续
有时间会整理下覆盖率测试(jacoco)和代码审核工具(Gerrit)