背景

在Android开发过程中,为了提高效率,我们会使用自动编译来提高我们版本迭代过程中的app编译.我的项目中目前使用的是Gradle+Jenkins+SVN来进行版本控制和自动编译的.

自动编译要控制好每一次的编译的代号和名称,方便出现问题时查找.为了实现这个唯一的编号,我们可能有很多种实现方式,这里我使用的是:SVN项目名称\_分支名称\_APP版本号\_SVN版本号\_build版本号,如:QQ_GroupChat_8.0.0_4585_256

自动编译,肯定是让机器自己去自动更新这些变量,那么如何在gradle中获取呢?

获取SVN版本号

在获取svn版本号之前先判断是否有Jenkins,如果有则从Jenkins中获取,没有在从其他地方获取.

判断是否有Jenkins

/**
 * 判断是否有jenkins
 * @return
 */
boolean isInJenkins() {
    Map<String, String> map = System.getenv()

    if (map == null) {
        return false
    }
    String str = map.get("Path")
    if (str != null) {
        //it's windows
        return false;
    } else {
        str = ""
        Iterator it = map.iterator();
        while (it.hasNext()) {
            str += it.next();
        }
        if (str.contains("jenkins")) {
            return true
        } else {
            return false;
        }
    }
    return false
}

OS中获取SVN版本号

从OS中获取SVN版本号的过程如下:

/**
 * 获取svn版本号
 * @return
 */
def getSvnRevision() {
    new ByteArrayOutputStream().withStream { os ->
        def result = exec {
            executable = 'svn'
            args = ['info']
            standardOutput = os
        }
        def outputAsString = os.toString()
        def matchLastChangedRev = outputAsString =~ /Last Changed Rev: (\d+)/

        ext.svnRev = "${matchLastChangedRev[0][1]}".toInteger()
    }
    return svnRev
}

获取SVN版本号

最终获取SVN版本号的代码如下:

/**
 * 根据不同平台来获取版本号
 */
def getSvnRevisionByPlatform() {
    boolean flag = isInJenkins();
    if (flag) {
        ext.env = System.getenv()
        ext.svnNum = env.SVN_REVISION?.toInteger()
        return "$svnNum"
    } else {
        return getSvnRevision()
    }
}

获取Jenkins的build号

获取Jenkins的build号分为两步:

  1. 判断是否有Jenkins
  2. 获取build号
/**
 * 获取Jenkins Build 号
 * @return
 */
def getJenkinsBuildCode() {
    boolean flag = isInJenkins();
    if (flag) {
        ext.env = System.getenv()
        ext.buildNumber = env.BUILD_NUMBER?.toInteger()
        return "$buildNumber"
    } else {
        return 0
    }
}

如何输出?

获取到了SVN版本号和Jenkins的build号,如何输出呢?

我们需要在build.gradle的android{}中添加以下代码:

applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            // 输出apk名称为QQ_GroupChat_8.0.0_4585_256.apk
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                def fileName
                if (variant.buildType.name == "release") {
                    fileName = "QQ_GroupChat_${defaultConfig.versionName}_${getSvnRevisionByPlatform()}_${getJenkinsBuildCode()}.apk"
                } else {
                    fileName = "QQ_GroupChat_${defaultConfig.versionName}_${getSvnRevisionByPlatform()}_${getJenkinsBuildCode()}_debug.apk"
                }
                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
    }

好啦,大功告成,试试吧!


重要说明

想随时获取最新博客文章更新,请关注公共账号DevWiki,或扫描下面的二维码:

微信公共号