Android 使用gradle配置多环境打包,很简单,也很实用。
准备
需要改动的文件:
1.项目根目录下的`build.gradle`文件
2.项目**app**下的`build.gradle`文件
需要使用的文件:
1.项目配置文件`BuildConfig.java`文件
开始
第一步
项目根目录下的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重点内容