http://tech.glowing.com/cn/dai-ma-gui-fan-he-androidxiang-mu-zhong-de-xie-ke-yong-gong-ju/
这里主要讲一下关于代码规范的相关问题,和在Android项目中如何利用一些工具进行规范和检查。代码规范不是一个Android项目特有的问题,所以前部分内容是不单针对Android的。
代码规范一般是指在编程过程中的一系列规则规范。
一般来说代码规范可以分为两种。
假如是强制的,大家暂时也不能反抗,只能吐嘈吐嘈,我们需要关心和规范的是非强制性规范。
一般情况下代码规范应该包括以下东西:
假如你一个人单干,并且基本上也会这么继续下去的话,那这个东西对你不是太重要,随心就好,在这个流程里你就可以随意continue
, break
, return
或exit
。
我们先来看看以下几种代码规范不好的情况,虽然情况极端,但多少能看出些问题。
那么有一个好的代码规范有什么好处呢?
简单来说,代码规范就是为了做到车同轨,书同文。最终的目的就是为了节约时间,提高效率,降低沟通成本。
套用一句广告来说,适合自己的才是最好的。
到Android了,觉得无关的群众可以散了。
总体来说,Android的要求应该是要基于Java的。这里推荐Google和Sun的代码规范,大家可以借鉴或修改。
不论是在Android Studio或者Eclipse里,这些集成的IDE都对这些规范有很多人性化的提示,但它们在事后检查或可定制或跨IDE方面有些不足,所以我们需要一些辅助工具。
接下来这里会推荐几个代码分析工具帮助大家检查相关问题,主要环境是Android Studio和Gradle,但在Eclipse和Ant等其他环境下修改应该也能使用。
checkstyle
帮助开发者实现常用JAVA
代码规范的自动化检查。它的功能比较丰富,相对配置起来比较复杂,你需要根据自己的需求配置你想检查的东西,比如Annotations
,Block Checks
,Class Design
,Coding
,Duplicate Code
,Headers
,Imports
,Javadoc Comments
,Metrics
,Miscellaneous
,Modifiers
,Naming Conventions
,Regexp
,Size Violations
,Whitespace
。
首先,你要在build.gradle
里加入plugin
apply plugin: ‘checkstyle'
其次,由于gradle默认的checkstyle版本比较老,你需要更新版本才可以使用一些比较新的方法
checkstyle {
toolVersion '6.1.1'
showViolations true
}
再次,你需要把定义好的要求转化成config/checkstyle.xml
里的一项项定义。比如你在这里就可以找到Google和Sun规范转化过来的xml。你应该按照自己的实际需求来配置这个文件。在checkstyle
的官网上,你可以找到各项已经定义好的规则,添加到项目里。例如,这里我们要定义每行最大长度100个字符。
<module name="LineLength">
<property name="max" value="100"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
现在你就可以加入任务了。注意要把刚刚添加的xml文件添加至configFile
配置里。同时,你也可以用source
指定你的源代码所在目录,并用include
指明你希望检查的代码,用exclude
排除你希望在检查中忽略的代码。
task checkStyle(type: Checkstyle) {
configFile file("config/checkstyle.xml")
source fileTree('src')
include '**/*.java'
exclude '**/gen/**'
}
findbugs
是一个分析bytecode
并找出其中可疑部分的一个工具。它给项目字节码做一个全面扫描,通过一些通用规则去判断可能潜在的一些问题,比如性能,多线程安全等等。有些时候它也会给出很详细的说明,为什么这种做法不大好,蛮有意思的。例如:
DLSYNCHRONIZATIONONSHAREDCONSTANT: Synchronization on interned String
The code synchronizes on interned String.
private static String LOCK = "LOCK";
...
synchronized(LOCK) { ...}
...
Constant Strings are interned and shared across all other classes loaded by the JVM. Thus, this could is locking on something that other code might also be locking. This could result in very strange and hard to diagnose blocking and deadlock behavior. See http://www.javalobby.org/java/forums/t96352.html and http://jira.codehaus.org/browse/JETTY-352.
首先,在build.gradle
里加入plugin
apply plugin: 'findbugs'
其次定义任务,这个也非常简单。你需要用classes
指定临时生成的classes目录,source
指定源代码所在目录。同时,你可以用xml.enabled
或html.enabled
指定你希望输出的报告格式。
task findbugs(type: FindBugs) {
ignoreFailures = true
classes = fileTree('build/intermediates/classes/debug')
source = fileTree('src')
classpath = files()
effort = 'max'
reports {
xml.enabled = false
html.enabled = true
}
}
PMD
也是一个静态代码分析工具,它主要用来分析一些常见问题。
PMD
和Findbugs
功能上有很多重叠的地方,二者区别主要体现在分析对象上,Findbugs
扫描的是字节码,所以找到问题的级别有可能不一样。推荐大家可以各自选择,也可以两者都用
它有很多定义好的rule
,例如在Android
里,目前有三项规则:
CallSuperFirst
,它会检查在Activity
或Service
里的子类里,是否在错误位轩调用父类onCreate
等应该放在方法前的方法。 CallSuperLast
,和CallSuperFirst
,但它会检查一些应该在方法结束时才调用父类实现的情况。 DoNotHardCodeSDCard
,这也是一个常见错误,你应该用Environment.getExternalStorageDirectory()
而不是硬编码去取得扩展存储目录。目前为止PMD
对于Android
的检查项并不多,使用它主要是用来检查一些JAVA
中的常见错误。
首先,在build.gradle
里加入plugin
apply plugin: 'pmd'
其次定义任务,ruleSets
是需要检查的一些规则,大家可以根据需要自己修改。点击这里可以找到所有的预定义规则。
task pmd(type: Pmd) {
source fileTree('src')
ruleSets = [
'java-android',
'java-basic',
'java-braces',
'java-clone',
'java-codesize',
'java-comments',
'java-controversial',
'java-coupling',
'java-design',
'java-empty',
'java-finalizers',
'java-imports',
'java-j2ee',
'java-javabeans',
'java-junit',
'java-logging-jakarta-commons',
'java-logging-java',
'java-migrating',
'java-naming',
'java-optimizations',
'java-strictexception',
'java-strings',
'java-sunsecure',
'java-typeresolution',
'java-unnecessary',
'java-unusedcode'
]
reports {
xml.enabled = false
html.enabled = true
}
}
工具和方法很多,并且很多工具和方法有重复功能,大家都可以根据需要修改和调整。但需要切记: