Android Gradle配置多环境打包


准备

需要改动的文件:

1.项目根目录下的`build.gradle`文件

2.项目**app**下的`build.gradle`文件

需要使用的文件:

1.项目配置文件`BuildConfig.java`文件

    1

开始

    第一步

项目根目录下的build.gradle文件

So esay! 不解释,一看就懂!

// gradle配置项目环境,
// 切换环境方式或打包Apk方式:
//      1.使用Build Variants视图下app的Build Variant选项
//          开发环境(devDebug/devRelease)
//          测试环境(offlineDebug/offlineRelease)
//          生产环境(onlineDebug/onlineRelease)
//      2.gradle命令
ext {
    MINSDK_VERSION = 15//最小支持SDK
    TARGETSDK_VERSION = 25//最大支持SDK
    VERSION_NAME = "1.5.0"//项目版本名称
    ONLINE_NUM = 00//生产环境版本序号(公司内部测试使用)
    TEST_NUM = 05//测试环境版本序号(公司内部测试使用)
    DEV_NUM = 15//开发环境版本序号(公司内部测试使用)
}
//生产环境版本号
def getVersionName() {
    int online_num = rootProject.ext.ONLINE_NUM
    if (online_num > 0) {
        return String.format("%s.%s", rootProject.ext.VERSION_NAME, rootProject.ext.ONLINE_NUM)
    } else {
        return rootProject.ext.VERSION_NAME
    }
}
//测试环境版本号
def getTestVersionName() {
    int test_num = rootProject.ext.TEST_NUM
    if (test_num > 0) {
        return String.format("%s.%s", rootProject.ext.VERSION_NAME, rootProject.ext.TEST_NUM)
    } else {
        return rootProject.ext.VERSION_NAME
    }
}
//开发环境版本号
def getDevVersionName() {
    int dev_num = rootProject.ext.DEV_NUM
    if (dev_num > 0) {
        return String.format("%s.%s", rootProject.ext.VERSION_NAME, rootProject.ext.DEV_NUM)
    } else {
        return rootProject.ext.VERSION_NAME
    }
}
//git提交次数
static int gitVersionCode() {
    def count = "git rev-list HEAD --count".execute().text.trim()
    return count.isInteger() ? count.toInteger() : 0
}

 

    第二步

项目app下的build.gradle文件

重点来了!!!

 defaultConfig {
        applicationId "com.jusenr.gradletest2"
        minSdkVersion rootProject.ext.MINSDK_VERSION
        targetSdkVersion rootProject.ext.TARGETSDK_VERSION
        versionCode rootProject.gitVersionCode()
        versionName rootProject.ext.VERSION_NAME
        resValue "string", "app_name", "GradleTest"
        manifestPlaceholders = [APPLICATION_ID: applicationId,
                                UMENG_APP_KEY : "1234567890",
                                QQ_APP_ID     : "app1的QQ_APP_ID",
                                AMAP_KEY      : "app1的高德地图key"]
        //标记当前环境是否为测试环境(false)
        buildConfigField "boolean", "IS_JUST_TEST", "false"
        //默认API(生产环境)
        buildConfigField "String", "DOMAIN_NAME", "\"http://pic.qiantucdn.com/\""
        buildConfigField "String", "DOMAIN_NAME1", "\"http://tx.haiqq.com/\""
        //版本号(1.0.1),保留的固定值
        buildConfigField("String", "VERSION_NUMBER", "\"${rootProject.ext.VERSION_NAME}\"")
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

 

rootProject.ext.xxx就是项目根目录下build.gradle文件里设置的值用来在这里使用的。
原因呢就是将所有可能会变的值这样引入app的build.gradle,以后几乎就不会再改动这个文件了。

这里用versionCode rootProject.gitVersionCode()git仓库代码提交次数来代表versionCode

这里resValue "string", "app_name", "GradleTest"用来修改app名称
使用了这个参数,项目的res/values/strings.xml就不能再有app_name 字符串,不然冲突报错。

这里manifestPlaceholders = [APPLICATION_ID: applicationId,
UMENG_APP_KEY : "1234567890",
QQ_APP_ID : "app1的QQ_APP_ID",
AMAP_KEY : "app1的高德地图key"]
又来配置清单文件中的meta-data等第三次的东西。

IS_JUST_TEST配置的默认值,标记是否是测试环境

DOMAIN_NAME、DOMAIN_NAME1这个就是我们项目需要请求服务器使用的Api域名

VERSION_NUMBER 版本号

    第三步 

productFlavors {
        dev {
            applicationId 'com.jusenr.dev'
            resValue "string", "app_name", "GradleTest_dev"
            manifestPlaceholders = [APPLICATION_ID: applicationId]
            //标记当前环境是否为测试环境(true)
            buildConfigField "boolean", "IS_JUST_TEST", "true"
            //开发环境API地址
            buildConfigField "String", "DOMAIN_NAME", "\"http://tx.haiqq.com/\""
            buildConfigField "String", "DOMAIN_NAME1", "\"http://tx.haiqq.com/\""
            versionName = "D" + rootProject.getDevVersionName()
        }
        offline {
            applicationId 'com.jusenr.offline'
            resValue "string", "app_name", "GradleTest_offline"
            manifestPlaceholders = [APPLICATION_ID: applicationId]
            //标记当前环境是否为测试环境(true)
            buildConfigField "boolean", "IS_JUST_TEST", "true"
            //测试环境API地址
            buildConfigField "String", "DOMAIN_NAME", "\"http://pic1.16pic.com/\""
            buildConfigField "String", "DOMAIN_NAME1", "\"http://tx.haiqq.com/\""
            versionName = "T" + rootProject.getTestVersionName()
        }
        online { versionName = "V" + defaultConfig.versionName }
//        huodong { versionName = "V" + defaultConfig.versionName }
//        GooglePaly { versionName = "V" + defaultConfig.versionName }
//        xiaomi { versionName = "V" + defaultConfig.versionName }
//        umeng { versionName = "V" + defaultConfig.versionName }

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

 

渠道配置:
dev开发环境
offline测试环境
online生产环境
其他就是各渠道了
在dev/offline中给默认的配置重新赋值来达到不同环境打包

就是这么简单。

    第四步

public final class BuildConfig {
  public static final boolean DEBUG = false;
  public static final String APPLICATION_ID = "com.jusenr.gradletest2";
  public static final String BUILD_TYPE = "release";
  public static final String FLAVOR = "online";
  public static final int VERSION_CODE = 11;
  public static final String VERSION_NAME = "V1.5.0";
  // Fields from build type: release
  public static final boolean LOG_DEBUG = false;
  // Fields from default config.
  public static final String DOMAIN_NAME = "http://pic.qiantucdn.com/";
  public static final String DOMAIN_NAME1 = "http://tx.haiqq.com/";
  public static final boolean IS_JUST_TEST = false;
  public static final String VERSION_NUMBER = "1.5.0";
}

 

使用BuildConfig 下我们配置的变量初始化项目。ok!

// gradle配置项目环境,
// 切换环境方式或打包Apk方式:
// 1.使用Build Variants视图下app的Build Variant选项
// 开发环境(devDebug/devRelease)
// 测试环境(offlineDebug/offlineRelease)
// 生产环境(onlineDebug/onlineRelease)
// 2.gradle命令

最后贴出源码:

 

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "26.0.0"
    defaultConfig {
        applicationId "com.jusenr.gradletest2"
        minSdkVersion rootProject.ext.MINSDK_VERSION
        targetSdkVersion rootProject.ext.TARGETSDK_VERSION
        versionCode rootProject.gitVersionCode()
        versionName rootProject.ext.VERSION_NAME
        resValue "string", "app_name", "GradleTest"
        manifestPlaceholders = [APPLICATION_ID: applicationId,
                                UMENG_APP_KEY : "1234567890",
                                QQ_APP_ID     : "app1的QQ_APP_ID",
                                AMAP_KEY      : "app1的高德地图key"]
        //标记当前环境是否为测试环境(false)
        buildConfigField "boolean", "IS_JUST_TEST", "false"
        //默认API(生产环境)
        buildConfigField "String", "DOMAIN_NAME", "\"http://pic.qiantucdn.com/\""
        buildConfigField "String", "DOMAIN_NAME1", "\"http://tx.haiqq.com/\""
        //版本号(1.0.1),保留的固定值
        buildConfigField("String", "VERSION_NUMBER", "\"${rootProject.ext.VERSION_NAME}\"")
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    signingConfigs {
        release {
            storeFile file("../gradletest.jks")
            storePassword "123456"
            keyAlias "gradletest"
            keyPassword "123456"
        }
    }
    buildTypes {
        release {
            // 不显示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            minifyEnabled false
            shrinkResources false
            zipAlignEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            // 显示Log
            buildConfigField "boolean", "LOG_DEBUG", "true"
            minifyEnabled false
            shrinkResources false
            signingConfig signingConfigs.release
        }
    }
    lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }
    //源码集
    sourceSets {
        main {
            java.srcDirs = ['src/main/java']
            jniLibs.srcDirs = ['libs']
            assets.srcDirs = ['src/main/assets']
        }
    }
    dexOptions {
        javaMaxHeapSize "2g"
    }

    //编译过滤器'release'/'debug'
//    variantFilter { variant ->
//        def buildType = variant.buildType.name
//        def flavorName = variant.getFlavors().get(0).name// 根据构建类型,自动过滤渠道
//
//        //过滤掉类型
//        if (buildType.equalsIgnoreCase('debug')) {
//            println "======================="
//            println "variantFilter " + flavorName + " " + buildType
//            variant.setIgnore(true)
//        }
//    }

    //产品渠道配置
    productFlavors {
        dev {
            applicationId 'com.jusenr.dev'
            resValue "string", "app_name", "GradleTest_dev"
            manifestPlaceholders = [APPLICATION_ID: applicationId]
            //标记当前环境是否为测试环境(true)
            buildConfigField "boolean", "IS_JUST_TEST", "true"
            //开发环境API地址
            buildConfigField "String", "DOMAIN_NAME", "\"http://tx.haiqq.com/\""
            buildConfigField "String", "DOMAIN_NAME1", "\"http://tx.haiqq.com/\""
            versionName = "D" + rootProject.getDevVersionName()
        }
        offline {
            applicationId 'com.jusenr.offline'
            resValue "string", "app_name", "GradleTest_offline"
            manifestPlaceholders = [APPLICATION_ID: applicationId]
            //标记当前环境是否为测试环境(true)
            buildConfigField "boolean", "IS_JUST_TEST", "true"
            //测试环境API地址
            buildConfigField "String", "DOMAIN_NAME", "\"http://pic1.16pic.com/\""
            buildConfigField "String", "DOMAIN_NAME1", "\"http://tx.haiqq.com/\""
            versionName = "T" + rootProject.getTestVersionName()
        }
        online { versionName = "V" + defaultConfig.versionName }
//        huodong { versionName = "V" + defaultConfig.versionName }
//        GooglePaly { versionName = "V" + defaultConfig.versionName }
//        xiaomi { versionName = "V" + defaultConfig.versionName }
//        umeng { versionName = "V" + defaultConfig.versionName }

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

    //Apk包名自定义
    applicationVariants.all {
        variant ->
            def apkFileName = rootProject.getVersionName()
            if ("debug" == variant.buildType.getName() && "dev" == variant.flavorName) {
                apkFileName = rootProject.getDevVersionName()
            }
            if ("release" == variant.buildType.getName() && "dev" == variant.flavorName) {
                apkFileName = rootProject.getTestVersionName()
            }
            if ("release" == variant.buildType.getName() && "dev" != variant.flavorName) {
                apkFileName = defaultConfig.versionName
            }
            variant.outputs.each {
                output ->
                    def outputFile = output.outputFile
                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
                        def fileName = outputFile.name.replace(".apk", "-${apkFileName}.apk")
                        output.outputFile = new File(outputFile.parent, fileName)
                    }
            }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    //umeng
    compile 'com.umeng.analytics:analytics:latest.integration'
    //glide
    compile 'com.github.bumptech.glide:glide:4.0.0-RC1'
}

//编译结束后删除unaligned包
android.applicationVariants.all {
    variant ->
        variant.assemble.doLast {
            variant.outputs.each {
                output ->
                    println "aligned " + output.outputFile
                    println "unaligned " + output.packageApplication.outputFile

                    File file = output.packageApplication.outputFile;
                    if (variant.buildType.zipAlignEnabled && file.getName().contains("unaligned")) {
                        println "deleting " + file.getName()
                        file.delete()
                    }
            }
        }
}

可以看到,更改包名,使不同环境的app同时安装在一个设备上。

简单使用的代码:

 

Glide.with(this)
                .load(BuildConfig.DOMAIN_NAME + "58pic/17/89/50/55a65ec4979a9_1024.jpg")
                .into(iv_image)
                .onLoadFailed(getResources().getDrawable(R.mipmap.ic_launcher));
        Glide.with(this)
                .load(BuildConfig.DOMAIN_NAME + "00/19/98/16pic_1998000_b.jpg")
                .into(iv_image1)
                .onLoadFailed(getResources().getDrawable(R.mipmap.ic_launcher));
        Glide.with(this)
                .load(BuildConfig.DOMAIN_NAME + "uploads/allimg/150401/200234AJ-5.jpg")
                .into(iv_image2)
                .onLoadFailed(getResources().getDrawable(R.mipmap.ic_launcher));

最后加上万能的传送门:
https://github.com/Jusenr/GradleTest2重点内容
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值