Gradle多渠道多环境打包自动重命名

概述

在公司开发时,一般会模拟出几套环境,ps,测试环境、准生产环境、发布环境等,同时 Android 市场繁多,为了方便后期数据分析,在发布的时候还要添加一个渠道统计,一般会用到友盟统计,这就给我们的打包带来了麻烦。

gradle

好在android studio的gradle脚本十分强大,给我们的构建带来了方便。

首先,我们定义一个配置文件,方便后面管理
gradle.properties,因为我的项目是区分中英文的,所以定义了两个packageName,打包的时候也算是两个产品

gradle.properties:

// build_tools版本号
ANDROID_BUILD_TOOLS_VERSION=22.0.1
// build_dk版本号
ANDROID_BUILD_SDK_VERSION=22

// version_name
VERSION_NAME=2.1
// version_code
VERSION_CODE=2100
// 包名
// PACKAGE= xxxx
// english version
PACKAGE= xxxx.en

//minSdkVersion
ANDROID_BUILD_MIN_SDK_VERSION=15
//targetSdkVersion
ANDROID_BUILD_TARGET_SDK_VERSION=22
// grade_version
GRADLE = com.android.tools.build:gradle:1.5.0

build.gradle(app 工程目录下):

//声明是Android程序,和library区别
apply plugin: 'com.android.application'
// 因为项目中使用了retrolambda
apply plugin: 'me.tatarka.retrolambda'

// 打包时间
def releaseTime() {
    return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}

android {
//编译SDK的版本
    compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
    // build tools的版本
    buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION

    defaultConfig {
    //应用的包名,定义在gradle.properties
        applicationId project.PACKAGE
        minSdkVersion Integer.parseInt(ANDROID_BUILD_MIN_SDK_VERSION)
        targetSdkVersion Integer.parseInt(ANDROID_BUILD_TARGET_SDK_VERSION)
        versionCode Integer.parseInt(project.VERSION_CODE)
        versionName project.VERSION_NAME

        // dex突破65535的限制,为大程序而设
        multiDexEnabled true
        // AndroidManifest.xml 里面CHANNEL的value为 ${CHANNEL_VALUE}
        manifestPlaceholders = [CHANNEL_VALUE: "name"]
    }

    //执行lint检查,有任何的错误或者警告提示,都会终止构建,我们可以将其关掉。
    lintOptions {
        checkReleaseBuilds false
        abortOnError false
        // 防止在发布的时候出现因MissingTranslation导致Build Failed!
        disable 'MissingTranslation'
    }

    dexOptions {
        incremental true
        javaMaxHeapSize "8g"
        jumboMode = true
        preDexLibraries = false
        threadCount ="8"
    }

    //签名
    signingConfigs {
        debug {
        }
        relealse {
            storeFile file('xxx.keystore')
            storePassword '***'
            keyAlias 'xxx'
            keyPassword '***'
        }
    }
    // 打包
    buildTypes {
    //debug  版本
//        debug {
//            buildConfigField "int", "ENV", "0"
//            minifyEnabled true
//            zipAlignEnabled true
//            shrinkResources true
//            proguardFile 'proguard-rules.pro'
//            signingConfig signingConfigs.relealse
//        }
//        pre {
//            buildConfigField "int", "ENV", "1"
//            minifyEnabled false
//            zipAlignEnabled false
//            shrinkResources false
//            signingConfig signingConfigs.relealse
//        }
//        online {
//            buildConfigField "int", "ENV", "2"
//            minifyEnabled false
//            zipAlignEnabled false
//            shrinkResources false
//            signingConfig signingConfigs.relealse
//        }
        release {
        // 定义ENV变量,可以通过BuildConfig.ENV 来获取,进行一些接口环境变化的操作
            buildConfigField "int", "ENV", "2"
            //混淆
            minifyEnabled true
            //Zipalign优化
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources true
            //混淆配置文件
            proguardFile 'proguard-rules.pro'
            //签名
            signingConfig signingConfigs.relealse
        }
    }

    //渠道Flavors
    productFlavors {
        Market_Google_Play {}
//        Market_xiaomi {}
//        Market_wandoujia {}
//        Market_Default {}
//        Market_Amazon {}
//        Market_yingyongbao {}
//        Market_360 {}
//        Market_baidu {}
    }

    // Java版本
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

// 替换manifest中定义的占位符
    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [CHANNEL_VALUE: name]
    }

    // apk输出重命名
    applicationVariants.all { variant ->
        variant.outputs.each { output ->

            // oldName
            def outputFile = output.outputFile

            if (outputFile != null && outputFile.name.endsWith('.apk')){

                // 获取中英文版本
                def isEn = variant.applicationId.endsWith('.en')
                def newName = ''
                def version= "-v${defaultConfig.versionName}"
                def time = "-${releaseTime()}.apk"
                def enName = 'appEN'
                def cnName = 'appCN'

                // release版本
//                if(variant.buildType.name.equals('release')) {
//
//                    // 获取渠道号
//                    def productFlavor = variant.productFlavors[0].name
//
//                    if (isEn) {
//                        newName = enName + version + '-' + productFlavor + time
//
//                    } else {
//                        newName = cnName + version + '-' + productFlavor + time
//                    }
//                }else if (variant.buildType.name.equals('pre')){
//                    if (isEn) {
//                        newName = enName + version + '-pre-online' + time
//
//                    } else {
//                        newName = cnName + version + '-pre-online'  + time
//                    }
//                }else if (variant.buildType.name.equals('online')){
//                    if (isEn) {
//                        newName = enName + version + '-online'  + time
//
//                    } else {
//                        newName = cnName + version + '-online'  + time
//                    }
//                }else{
                    if (isEn) {
                        newName = enName + version + '-debug'  + time

                    } else {
                        newName = cnName + version + '-debug'  + time
                    }
//                }
                output.outputFile = new File(outputFile.parent, newName)
            }
        }
    }
}

retrolambda {
    javaVersion JavaVersion.VERSION_1_7
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile 'com.android.support:design:22.2.1'
    compile 'com.android.support:recyclerview-v7:22.2.1'
    compile 'com.annimon:stream:1.0.1'
    compile project(':mylibrary')
}

最后会在app/build/outputs/apk下生成相应的文件
debug:name-version-debug-time.apk
release: name-version-productFlavors-time.apk

AndroidManifest.xml

<application>
<meta-data
            android:name="UMENG_APPKEY"
            android:value="54d32a3afd98c511cf000629" />
        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${CHANNEL_VALUE}" />

    </application>
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 开发中,Gradle 是一个非常重要的构建工具,可以用来构建和打包 Android 应用程序。Gradle 插件是一种工具,可以扩展 Gradle 的功能,使其能够支持更多的功能。而多渠道打包Android 应用程序开发中非常重要的一个方面,它可以让我们将应用程序打包成不同的版本,并发布到不同的应用商店或市场上。 在 Android Studio 中,我们可以通过自定义 Gradle 插件来实现多渠道打包,具体步骤如下: 1. 创建 Gradle 插件项目 在 Android Studio 中创建一个新项目,选择 Gradle 插件项目模板。这将创建一个 Gradle 插件项目,并生成一些默认的代码和文件。 2. 实现多渠道打包 在插件项目中,我们需要实现多渠道打包的功能。这可以通过 Gradle 的 productFlavors 和 buildTypes 配置来实现。我们可以定义多个 productFlavors,并为每个 productFlavor 配置不同的参数,例如应用程序的包名、应用程序名称等。在 buildTypes 中,我们可以为每个 buildType 配置不同的参数,例如应用程序的版本号、是否开启混淆等。 3. 打包应用程序 在插件项目中,我们可以编写一个 Gradle 任务来实现应用程序的打包。这个任务可以使用 Gradle 提供的 assemble 任务来实现。我们可以为每个 productFlavor 和 buildType 配置不同的打包参数,并使用 Gradle 的 assemble 任务来生成应用程序的 APK 文件。 4. 发布应用程序 在插件项目中,我们可以编写一个 Gradle 任务来实现应用程序的发布。这个任务可以使用 Gradle 提供的 uploadArchives 任务来实现。我们可以为每个 productFlavor 和 buildType 配置不同的发布参数,并使用 Gradle 的 uploadArchives 任务将应用程序发布到不同的应用商店或市场上。 总的来说,自定义 Gradle 插件多渠道打包Android 应用程序开发中非常重要的一个方面。通过自定义 Gradle 插件,我们可以实现更加灵活和高效的应用程序打包和发布。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值