美文网首页程序员联盟Android开发经验谈安卓笔记侠
Android Gradle 常用使用场景实现方式的总结

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

作者: 亦枫 | 来源:发表于2017-09-16 12:10 被阅读177次

    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

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

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

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

    相关文章

      网友评论

        本文标题:Android Gradle 常用使用场景实现方式的总结

        本文链接:https://www.haomeiwen.com/subject/iqvysxtx.html