开篇废话
在项目中写代码时偶尔会不注意,从而导致了隐形的bug产生,平时也发现不了,比如说在自定义View时使用了TypedArray却忘记了recycle()回收,所以我就想到通过写Gradle脚本的方式来检查代码。
先讲思路
- 遍历所有的java文件
- 检查代码是否有问题
- 检查比较耗时设定每2小时检查一次
直接上代码
废话就不再多说了,直接上代码。
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
task(CheckCodeSpec) {
def nowTime = System.currentTimeMillis()
def CHECK_CODE_JSON_PATH = "gradle/check_code_spec_config.json" //生成的文件
def CHECK_LAST_TIME = "check_last_time" //文件json的Key值,Value是上次检查的时间
def CHECK_CYCLE_MINUTE = 2 //每过多久检查一次,单位小时
def CHECK_CYCLE_MS = CHECK_CYCLE_MINUTE * 60 * 60 * 1000
def file = file(CHECK_CODE_JSON_PATH)
if (!file.exists()) {
file.createNewFile()
file.write("{}")
}
def slurper = new JsonSlurper()
def checkCodeMap = slurper.parseText(file.text)
if (checkCodeMap[CHECK_LAST_TIME] != null) {
def lastTime = checkCodeMap[CHECK_LAST_TIME]
if (nowTime - lastTime > CHECK_CYCLE_MS) {
startCheckCodeSpec()
checkCodeMap[CHECK_LAST_TIME] = nowTime
} else {
println "\nNot check spec code within $CHECK_CYCLE_MINUTE hour\n"
}
} else {
println "\nNot find check spec code lastTime\n"
checkCodeMap[CHECK_LAST_TIME] = 0
}
def output = new JsonOutput()
def checkCodeJson = output.toJson(checkCodeMap)
file.write(checkCodeJson)
}
def startCheckCodeSpec() {
def startTime = System.currentTimeMillis()
println "\nStart check spec code ..."
// def appSrcDir = file('src/main/java/com/soft/blued/')
def appSrcDir = file(rootDir.getAbsoluteFile())
def javaSrcFile
def javaSrcFileName
def javaSrcFileText
def javaSrcFileCount = 0
appSrcDir.eachFileRecurse(groovy.io.FileType.FILES, new Closure(null) {
void doCall(Object[] args) {
javaSrcFile = (File) args[0]
javaSrcFileName = javaSrcFile.name
if (javaSrcFileName.matches("\\w*\\.java")) {
javaSrcFileText = javaSrcFile.text
javaSrcFileCount += 1
if (javaSrcFileText.indexOf("android.content.res.TypedArray") > 0) {
if (javaSrcFileText.indexOf("recycle()") <= 0) {
showForbiddenWithLack("recycle()", javaSrcFileName)
}
}
if (javaSrcFileText.indexOf("android.os.Message") > 0) {
if (javaSrcFileText.indexOf("new Message()") > 0) {
showForbiddenWithDisable("new Message()", javaSrcFileName)
}
}
}
}
def showForbiddenWithLack(forbiddenMethod, fileName) {
def message = "\'" + forbiddenMethod + "\' is missing of Class!! [ " + fileName + " ]"
throw new Exception(message)
}
def showForbiddenWithDisable(forbiddenMethod, fileName) {
def message = "\'" + forbiddenMethod + "\' is not available of Class!! [ " + fileName + " ]"
throw new Exception(message)
}
})
def takeTime = System.currentTimeMillis() - startTime
println "Check spec code finish! \n[Total Scan " + javaSrcFileCount + " File in " + takeTime + "ms]\n"
}
整个代码还是比较简单的,只对两点进行了检查:
- TypedArray是否使用recycle()。
- Handler中的Message的创建是否使用了推荐的Message.obtain()。
脚本写完了,具体如何在项目中使用呢?
在项目工程的build.gradle中添加以下代码:
//=====================code spec check=====================
apply from: './gradle/check_code_spec.gradle'
因为我是每2小时检查一次,所以会生成一个json文件来记录上次检查的时间,为了多人协作开发比较方便,所以还需要在.gitignore文件中添加配置:
# 代码检查生成的配置文件
check_code_spec_config.json
写在后面
现在只是对两点进行了检查,如果你们还有什么其它更好的想法,也可以留言给我,我可以添加到代码中,谢谢大家。
更多内容戳这里(整理好的各种文集)