Android中的CheckStyle

背景

简单一句话:CheckStyle解放了团队编码规范的审核。

CheckStyle主要实现了事实检测代码是否符合已经定义的规范,比如静态变量需要大写,函数名不超过20字符等。当发现这些检测不符合规范,则发出警告或错误。

简单来说,checkstyle检测了(更多信息:checkstyle):

Annotations
Block Checks
Class Design
Coding
Headers
Imports
Javadoc Comments
Metrics
Miscellaneous
Modifiers
Naming Conventions
Regexp
Size Violations
Whitespace

Android中的配置

由于checkstyle功能丰富,如果自行配置,相对较为复杂,所以在其官网谷歌、sun都有提供范例。接下来简要介绍如何在gradle中配置checkstyle。

配置plugin

build.gradle中,新增插件:

1
apply plugin: 'checkstyle'

默认checkstyle的版本为5.9,如果觉得版本较老,可以配置版本(目前最新版本为6.13,但是不兼容,最高可用版本为6.1.1):

1
2
3
checkstyle {
toolVersion '6.1.1'
}

检测任务

在添加完插件之后,需要添加检测的任务:

1
2
3
4
5
6
7
8
9
10
11
task checkstyle(type: Checkstyle) {
configFile rootProject.file('checkstyle.xml')
// source fileTree('src')
source 'src/main/java'
ignoreFailures false
showViolations true
include '**/*.java'
exclude '**/gen/**'

classpath = files()
}

检测配置

可以看到上一个步骤有checkstyle.xml文件,这个文件就是检测配置文件,里面包含了检测的规则,可以参考AndroidKnife/check这里的配置。

检测插件

如果是使用studio的话,有一系列插件可以方便检测,输入QAPlug并进行搜索即可安装,其中包括check styleFindBugsPMDHammurapi

Ref

checkstyle/checkstyle
Google Java Style
Code Conventions for the Java Programming Language
BeautyStyle

顺便带上目前使用的check style,可在AndroidKnife/Utils找到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?xml version="1.0"?><!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.2//EN"
"http://www.puppycrawl.com/dtds/configuration_1_2.dtd">


<module name="Checker">
<!--module name="NewlineAtEndOfFile"/-->
<module name="FileLength" />
<module name="FileTabCharacter" />

<!-- Trailing spaces -->
<module name="RegexpSingleline">
<property name="format" value="\s+$" />
<property name="message" value="Line has trailing spaces." />
</module>

<!-- Space after 'for' and 'if' -->
<module name="RegexpSingleline">
<property name="format" value="^\s*(for|if)\(" />
<property name="message" value="Space needed before opening parenthesis." />
</module>

<!-- For each spacing -->
<module name="RegexpSingleline">
<property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])" />
<property name="message" value="Space needed around ':' character." />
</module>

<module name="TreeWalker">
<!--<property name="cacheFile" value="${checkstyle.cache.file}"/>-->

<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<!--module name="JavadocMethod"/-->
<!--module name="JavadocType"/-->
<!--module name="JavadocVariable"/-->
<!--module name="JavadocStyle"/-->


<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module name="ConstantName" />
<module name="LocalFinalVariableName" />
<module name="LocalVariableName" />
<module name="MemberName" />
<module name="MethodName">
<property name="format" value="^[a-z][a-zA-Z0-9_]*$" />
</module>
<module name="PackageName" />
<module name="ParameterName" />
<module name="StaticVariableName" />
<module name="TypeName">
<property name="format" value="^[A-Z][a-zA-Z0-9_]*$" />
</module>


<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport" />
<module name="IllegalImport" />
<module name="RedundantImport" />
<module name="UnusedImports">
<property name="processJavadoc" value="true" />
</module>


<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="LineLength">
<property name="max" value="150" />
<property name="ignorePattern"
value="^package.*|^import.*|a href|href|http://|https://|ftp://" />

</module>
<module name="MethodLength" />
<module name="ParameterNumber" />


<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="GenericWhitespace" />
<module name="EmptyForIteratorPad" />
<module name="MethodParamPad" />
<module name="NoWhitespaceAfter" />
<module name="NoWhitespaceBefore" />
<module name="OperatorWrap" />
<module name="ParenPad" />
<module name="TypecastParenPad" />
<module name="WhitespaceAfter" />
<module name="WhitespaceAround" />


<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
<!--module name="ModifierOrder"/-->
<module name="RedundantModifier" />


<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<module name="AvoidNestedBlocks" />
<module name="EmptyBlock" />
<module name="LeftCurly" />
<module name="NeedBraces" />
<module name="RightCurly" />


<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<!--module name="AvoidInlineConditionals"/-->
<module name="CovariantEquals" />
<module name="EmptyStatement" />
<module name="EqualsAvoidNull" />
<module name="EqualsHashCode" />
<!--<module name="HiddenField"/>-->
<module name="IllegalInstantiation" />
<module name="InnerAssignment" />
<!--module name="MagicNumber"/-->
<module name="MissingSwitchDefault" />
<module name="RedundantThrows" />
<module name="SimplifyBooleanExpression" />
<module name="SimplifyBooleanReturn" />

<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<!--module name="DesignForExtension"/-->
<!--module name="FinalClass"/-->
<module name="HideUtilityClassConstructor" />
<module name="InterfaceIsType" />
<!--<module name="VisibilityModifier"/>-->


<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="ArrayTypeStyle" />
<!--module name="FinalParameters"/-->
<module name="TodoComment" />
<module name="UpperEll" />
</module>
</module>