Android Studio之Gradle自动化构建打包

  最近一年来的工作最让我深有感悟的就是测试动不动就是问我要测试包,弄的我实在是叫苦不堪。今天正好有个工作空档期,也有些意外看到过些类似的博文,正好在这个工作空档期实现了Window上跑Gradle脚本自动构建Android项目。

  首先,开发环境:

    系统:Win7

    Gradle版本:4.2

    Android Studio: 2.2.2

  关于Gradle下android{}的配置字段说明如下:

    defaultConfig{} 默认配置,是ProductFlavor类型。它共享给其他ProductFlavor使用
    sourceSets{ } 源文件目录设置,是AndroidSourceSet类型。
    buildTypes{ } BuildType类型
    signingConfigs{ } 签名配置,SigningConfig类型
    productFlavors{ } 产品风格配置,ProductFlavor类型
    testOptions{ } 测试配置,TestOptions类型
    aaptOptions{ } aapt配置,AaptOptions类型
    lintOptions{ } lint配置,LintOptions类型
    dexOptions{ } dex配置,DexOptions类型
    compileOptions{ } 编译配置,CompileOptions类型
    packagingOptions{ } PackagingOptions类型
    jacoco{ } JacocoExtension类型。 用于设定 jacoco版本
    splits{ } Splits类型

  脚本构建工作如下:

    关于Gradle配置编译Apk相关签名如下:  

android {
    signingConfigs {
        release {
            storeFile file('E:GsaftykeystoreName.keystore') //绝对路径
            storePassword "12345678"
            keyAlias "alias"
            keyPassword "12345678"
        }
    }

}

  构建类型(开发过程中会不断的提交测试debug包到测试人员去测试)

    如下代码仅做参考:

buildTypes {
        release {
            minifyEnabled false
            shrinkResources false
            zipAlignEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }

        debug {
            minifyEnabled false
            shrinkResources false
            zipAlignEnabled false
        }

        custom {
            minifyEnabled false
            shrinkResources false
            zipAlignEnabled false
        }

        sourceSets {
            main {
                jni.srcDirs = []
            }
        }
    }

  多渠道打包构建不同渠道的多个类型apk

    这里不同的渠道会根据构建类型生成对应的apk,其对应关系为渠道种类数*构建编译类型数等于编译出的APK数。

    /*多渠道包*/
    productFlavors{
        tencent{
            applicationId "com.domin.armn"
            versionCode "1.0"
            versionName "1.2.0"
            manifestPlaceholders = [appName: "tencent"]
        }
        
        baidu{
            applicationId "com.domin.armn"
            versionCode "1.0"
            versionName "1.2.0"
            manifestPlaceholders = [appName: "baidu"]
        }
    }

  自定义生成的APK包名称

    例如:module_flavor-version-time-buildtype.apk 

    在APP下的build.gradle根目录下声明如下:

//获取当前时间
def getCurrentTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
} 

    在Android{}目录下声明如下:  

/*apk重命名*/
    android.applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def outputFile = output.outputFile
            if (outputFile != null && outputFile.name.endsWith('.apk')) {
                def buildType = variant.buildType.name
                //这里修改apk文件名,格式为 module_flavor-version-time-buildtype.apk
                def fileName = "Gsafety_${variant.productFlavors[0].name}-V${defaultConfig.versionName}-${getCurrentTime()}-${buildType}.apk"
                output.outputFile = new File(outputFile.parent, fileName)
            }
        }
    }

  进阶配置项

    以上所有的设置尚且不能够完全满足自动化编译,仍然需要用户手动输入命令去运行编译APK包,这当然不是我们最想要的结果。

    Gradle执行相关命令如下:     

      注:在使用编译命令之前请确保gradle已经加入环境变量,如果没加入可以通过./gradlew替代gradle(只能在项目根目录下使用)

      1编译所有productFlavor及对应所有buildType的apk.
        $gradle assemble   //仅仅执行项目打包所必须的任务集
        $gradle build           //执行项目打包所必须的任务集,以及执行自动化测试,所以会较慢
        如果当前Project包含多个Module,在Project根目录执行gradle assemble会编译所有的Module

      2编译指定productFlavor及buildType的apk
        $gradle assemble[productFlavor][buildType]
        如果缺失某参数,则会把该参数的所有配置都进行编译,即如果运行gradle assembleflavor,则会编译出flavor所有buildType的apk
        例如:
          $gradle assemble
          $gradle assembleflavorRelease 
          $gradle assembleflavorDebug
        注:gradle支持命令缩写,上面两个命令也可以写成如下格式
          $gradle a
          $gradle ass
          $gradle aR
          $gradle assflavorR
          $gradle aD
          $gradle assflavorD

    在项目根目录下创建一个指定的文件夹(用于编译跑脚本用),例如.config,然后在该目录下分辨创建.bat文件(win7上批处理后缀文件)和签名文件

      批处理文件如下build.bat:

      注意:这里可能会在CMD窗口出现中文乱码,这是由于便于问题,不会影响编译。

#快速编译打包apk脚本

echo  " **************************打包开始 ************************** "
sleep 1
#执行打包命令前,需要先定位到项目根目录
cd ..
#执行打包命令
gradle a

echo -e "**************************打包完成************************** "

#桌面右上角弹出通知
notify-send build.sh "打包完成!"

      创建签名文件sign.txt:

      签名文件之所以放到外边这里是为了更好的保护签名文件,尽量少的给其他人知道<安全考虑>。

android {
    signingConfigs {
        release {
            storeFile file('E:GsaftykeystoreName.keystore') //绝对路径
            storePassword "12345678"
            keyAlias "alias"
            keyPassword "12345678"
        }
    }

}

     将签名文件应用到app的build.gradle文件下的android{}:

//加载签名信息
    File configFile = file('../.config/sign.txt')
    if (configFile.exists()) {
        def signGradlePath = configFile.newReader().readLine().trim()
        println 'lucher, path:' + signGradlePath
        if (file(signGradlePath).exists()) {
            apply from: signGradlePath
        }
    }

   最后就是开发人员的福利了,在window机器上直接点击.bat文件执行批处理命令,即可在项目build目录下的apk目录下得到对应的apk包.