Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,目前也增加了基于Kotlin语言的kotlin-based DSL,抛弃了基于XML的各种繁琐配置。
AS创建项目完成后默认提供了debug
和release
两种环境的包,前者是测试包,后者是正式发布包。
在默认情况下,debug
和release
都共用同一套配置(版本名/版本号/第三方库APPID等)。如果每次打release
包都要修改配置为release
的信息,打包完继续修改后改为debug
信息继续开发,这无疑是一个很繁琐的过程。
gradle
可以很好的解决这一痛点。利用多渠道打包的特点来解决问题。
一般需要分别设置一下信息:
-
debug
和release
在手机上共存 -
api
接口的BaseUrl
- 应用名、应用图标和第三方库配置信息
- 版本号和版本名
debug
和release
在手机上共存
因为debug
和release
包名一致,所以同一台手机是无法同时安装的。applicationIdSuffix
可以在applicationId
上添加一个后缀用来区分。
// 给`debug`的包名添加后缀
buildTypes {
debug {
applicationIdSuffix ".debug" // 字符串随意取
}
}
假设applicationId
为com.android.test
,配置之后,debug
的包名则变成com.android.test.debug
,release
包名不变。
api
接口的BaseUrl
开发环境和生产环境使用的BaseUrl
肯定是不一样的,这就需要根据不同的环境来选择不同的URL了。
Build项目的时候,AS会根据类型从buildTypes
选择编译debug
还是release
。那就可以从这个角度入手,因为BaseUrl
是在Java
代码中使用,因此可以使用BuildConfigField
来自定义属性。
buildTypes {
debug {
buildConfigField("String", "BaseUrl" ,"\"https://www.debug.com/\"")
}
release {
buildConfigField("String", "BaseUrl" ,"\"https://www.release.com/\"")
}
}
在Java代码中使用 BuildConfig.BaseUrl
访问静态变量。
应用名、应用图标和第三方库配置信息
手机上同时安装debug
和release
两种包,很容易就搞混,最好是可以使用不同的logo和名称来加以区分。
另外,有些第三方SDK集成也需要区分不同环境的APPID
,例如高德地图SDK。
以上2中情况有一个共同点,那就是都是在AndroidManifest.xml
文件中配置的,那可以用manifestPlaceholders
来配置,顾名思义就是AndroidManifest
文件占位符的意思。
manifestPlaceholders
参数是一个Map<String, Object>
,因此可以配置多个值,每个值都是一个键值对key:value
形式。
在gradle
中的语法为
manifestPlaceholders = [key1: value1, key2:value2...]
因此可以这么写:
buildTypes {
debug {
manifestPlaceholders = [GD_MAP : "测试版本高德地图APPKEY",
AppName : "测试APP",
logo : "@mipmap/logo_debug"]
}
release {
manifestPlaceholders = [GD_MAP : "正式版本高德地图APPKEY",
AppName : "正式APP",
logo : "@mipmap/logo"]
}
}
然后再AndroidManifest.xml
中调用
<application
...
android:icon="${logo}"
android:label="${AppName}">
<!-- 高德地图KEY -->
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="${GD_MAP}"/>
...
</application>
版本号和版本名
不同环境如果使用不同的版本号和版本名,那就得想办法从buildTypes
中去修改版本信息。
在applicationVariants.all
中有这样两个方法
output.versionNameOverride
output.versionCodeOverride
android {
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.versionNameOverride = VERSION_NAME // 覆盖版本名
output.versionCodeOverride = VERSION_CODE // 覆盖版本号
}
}
}
那就可以在外面声明2个全局变量,VERSION_NAME
和VERSION_CODE
,然后在buildTypes
的debug
和release
中进行赋值,在最后打包的时候,获取到VERSION_NAME
和VERSION_CODE
的值进行版本信息覆盖。
完整代码
android {
// 开发环境的版本号、版本名
def VERSION_NAME_DEBUG
def VERSION_CODE_DEBUG
// 生产环境的版本号、版本名
def VERSION_NAME_RELEASE
def VERSION_CODE_RELEASE
buildTypes {
debug {
// 修改此处更改测试版本信息
VERSION_NAME_DEBUG = "1.2.3"
VERSION_CODE_DEBUG = 10
}
release {
// 修改此处更改正式版本信息
VERSION_NAME_RELEASE = "1.3.0"
VERSION_CODE_RELEASE = 15
}
}
applicationVariants.all { variant ->
variant.output.each { output ->
// 声明局部变量
def VERSION_NAME = "1.0.0"
def VERSION_CODE = 1
if (variant.buildType.name == "debug") {
VERSION_NAME = VERSION_NAME_DEBUG
VERSION_CODE = VERSION_CODE_DEBUG
} else if(variant.buildType.name == "release") {
VERSION_NAME = VERSION_NAME_RELEASE
VERSION_CODE = VERSION_CODE_RELEASE
}
output.versionNameOverride = VERSION_NAME
output.versionCodeOverride = VERSION_CODE
}
}
}
小结:
-
applicationIdSuffix
可以给applicationId
添加后缀,达到不同渠道不同包名的目的 -
buildConfigField
自定义属性值,BuildConfig.xxx
访问 -
manifestPlaceholders
设置AndroidManifest.xml
的占位符,参数为Map
类型 -
variant.outputs.each
可以设置打包参数,如版本信息、生成apk的名字和保存路径等
网友评论