Android Gradle 常用使用场景实现方式的总结

3,646 阅读4分钟

Gradle 作为一款灵活多变的构建插件,与 Android Studio 的结合,能够解决过去使用 Eclipse 开发 App 时所遇到的诸多问题。同时,基于 Groove 这样一款 DSL 语言的脚本特性,记住各种语法显然又是一件比较困难的事情。

事实上,Gradle 插件的常用使用场景并不是很多,也不需要死记硬背,或者完全学会 Groove 的所有使用方式。这里将 Android 开发中较为常用的 Gradle 使用场景总结出来,用于将来需要的时候有个参考。

多渠道打包

举一个最常见的多渠道使用场景,友盟统计,看看最基本的 Gradle 多渠道打包方式的用法。

修改 Manifest 文件中友盟统计的渠道名为引用变量(变量名自取):

<meta-data
    android:name="${UMENG_CHANNEL_VALUE}"
    android:value="Channel_ID" />

然后在 build.gradle 文件 productFlavors 配置项中添加渠道名,并统一设置到上面提到的变量名:

android {
    productFlavors {
        xiaomi {}
        yingyongbao {}
    }

    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
    }
}

执行打包 Task 的命令语句即可:

./gradle assembleRelease

或者有针对性的只打特定渠道包,如:

./gradle assembleXiaomiRelease

备注:在 Gradle projects 窗口中能够查看所有可执行的 Tasks 列表。这种原生态打包方式适合渠道名比较少的使用场景。当渠道多达数十个甚至上百个时,打包时间就会比较长,推荐其他打包方案,如:

自定义输出 APK 文件名

可以修改打包输出的 apk 文件名,添加时间戳、编译类型、版本信息等关键字,是 apk 文件更具识别性,如:

apply plugin: 'com.android.application'

def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

android {
    android.applicationVariants.all { variant ->
        variant.outputs.each { output ->
            output.outputFile = new File(output.outputFile.parent, rootProject.getName()
                    + "-" + buildType.name
                    + "-" + releaseTime()
                    + "-v" + defaultConfig.versionName
                    + "-" + defaultConfig.versionCode
                    + ".apk");
        }
    }
}

这里将项目名称添加到 apk 文件名中,也可以使用 applicationId 等,结果如下:

YFSample-release-2017-09-12-v1.0-1.apk

Debug 和 Release 相同签名

android {
    buildTypes {
        debug {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "boolean", "DEBUG_MODE", "true"
            signingConfig signingConfigs.config
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "boolean", "DEBUG_MODE", "false"
            signingConfig signingConfigs.config
        }
    }
}

这一步操作可以通过图形化界面操作,更方便一些。右键项目,点击 Open Module Settings,打开 Project Structure 窗口,在 Build Types 选项卡中设置。

隐藏签名信息

签名信息作为项目里最为私密的一部分内容,如果直接暴露在 build.gradle 文件中,显然不够安全。尤其是需要上传到 GitHub 等托管平台时。

比较妥当的做法是,在项目根目录下新建一个专门用来存储签名信息的文件,并且将其添加到 ignore 文件配置当中。具体操作过程如下:

第一步,新建一个 keystore.properties 文件:

ReleaseKeyPassword=sampleKeyPwd
ReleaseKeyAlias=sampleAlias
ReleaseStorePassword=sampleStorePwd
ReleaseStoreFile=../sample.jks

第二步,在 build.gradle 文件的最外层引入签名信息:

allprojects {
    afterEvaluate { project ->
        def propsFile = rootProject.file('keystore.properties')
        def configName = 'config'

        if (propsFile.exists() && android.signingConfigs.hasProperty(configName)) {
            def props = new Properties()
            props.load(new FileInputStream(propsFile))
            android.signingConfigs[configName].storeFile = file(props['ReleaseStoreFile'])
            android.signingConfigs[configName].storePassword = props['ReleaseStorePassword']
            android.signingConfigs[configName].keyAlias = props['ReleaseKeyAlias']
            android.signingConfigs[configName].keyPassword = props['ReleaseKeyPassword']
        }
    }
}

如此即可。其中第二步还有一种缩减版的写法,也可以直接使用:

def keystorePropertiesFile = rootProject.file("keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

android {
    signingConfigs {
        config {
            storeFile file(keystoreProperties['ReleaseStoreFile'])
            storePassword keystoreProperties['ReleaseStorePassword']
            keyAlias keystoreProperties['ReleaseKeyAlias']
            keyPassword keystoreProperties['ReleaseKeyPassword']
        }
    }
}

当然,隐藏签名信息的方式还有很多。比如配置在本地环境变量中,或者 build.gradle 文件中,或者编译时从命令行中动态读取输入内容等,设置不同,读取方式有所不同。

日志开关

在 app/build.gradle 文件中分别定义 debug 和 release 不同编译模式的控制变量,变量名可自由更改:

buildTypes {
    debug {
        buildConfigField "boolean", "DEBUG_MODE", "true"
    }
    release {
        buildConfigField "boolean", "DEBUG_MODE", "false"
    }
}

重新编译后,自动生成的 BuildConfig 类中包含上面定义的 DEBUG_MODE 属性,即可使用。

Log 日志开关更多解决方案,可参考:Android 中能够作为 Log 开关的一些操作以及安全性浅谈

环境分离

开发中测试服务器和生产服务器的同时使用也是很常见的场景之一,如何在一台设备中同时安装配置测试环境的 debug 包和生产环境的 release 包,也是需要面对的问题。不妨参考我的这篇文章:

Android 利用 Gradle 实现 app 的环境分离

参考链接

学习有关 Android、Gradle 和 Groove 更多详细信息,除了访问 Gradle 官方网站,推荐你阅读这些文章:

END

关于我:亦枫,博客地址:yifeng.studio/,新浪微博:IT亦枫

微信扫描二维码,欢迎关注我的个人公众号:安卓笔记侠

不仅分享我的原创技术文章,还有程序员的职场遐想