Android 用Gradle脚本代码检查

开篇废话

在项目中写代码时偶尔会不注意,从而导致了隐形的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

写在后面

现在只是对两点进行了检查,如果你们还有什么其它更好的想法,也可以留言给我,我可以添加到代码中,谢谢大家。

更多内容戳这里(整理好的各种文集)

你可能感兴趣的:(Android 用Gradle脚本代码检查)