Gradele 更多文章请看我的主页
Gradle 中的动态参数
这部分参数是不用写死的,可以在 Gradle 构建过程中由我们手动赋值,使用非常广泛,具体写法我老是记不住,每次用都得现 baidu
1. manifestPlaceholders
Gradle 中声明的 manifestPlaceholders
参数,在 AndroidManifest.xml
中可以通过 $hostName
的方式引用到
manifestPlaceholders 可以写在 Gradle 脚本 android{...}
DSL 中,常见的应用位置:
defaultConfig {...}
、productFlavors{...}
、buildTypes{...}
android {
defaultConfig {
manifestPlaceholders(["hostName":"www.example.com"])
}
}
可以在配置文件中的任何位置使用
<?xml .....>
<manifest ....>
<application ....>
<activity ....>
<intent-filter>
<data android:scheme="http" android:host="${hostName}"/>
</intent-filter>
</...>
</...>
</...>
2. buildConfigField
buildConfigField
方法会在生成 BuildConfig.java
时, 向其中插入该属性。日志模块我们就是依托这个参数,来统一控制 release 版本不打印日志
android {
defaultConfig {
buildConfigField("int", "i", "1234")
buildConfigField("String", "str", "\"some text\"")
buildConfigField("boolean", "isRelease", "true")
}
}
可以看到 build 后,BuildConfig 中有这个参数了
3. resValue
resValue
比大家可能见的少,用来向 res/values/strings.xml
中添加数据
android {
defaultConfig {
resValue("string", "app_name_test", "some text")
}
}
4. resConfigs
defaultConfig {
// 资源打包过滤
resConfigs("en", "ldltr")
}
resConfigs(...) 是系统资源过滤,同一类型的资源,只有 resConfigs{...} 声明的配置才能打入 APK 中,可以用在:defaultConfig {...}
、productFlavors{...}
、buildTypes{...}
中
en:
只选择英文ldltr:
方向性资源上只要从左到右的资源文件
变体
记住变体使用的单词:Variants
,变体也叫:差异化构建
脚本中 android{...} 之外的地方我们也可以通过 this.android.xxx 配置
1. 什么是变体
变体 Variants 这个概念来自 Gradle Android Plugin,单看 productFlavors{...}
、buildTypes{...}
都写在 android{...}
就能猜到了
那么变体是什么呢,就是我们打包 APK 得到的最终产物,图中就是,新版本的 Android Plugin 还多了一个 json 描述文件,写的都是打包该 APK 时的配置参数
注意看图中 APK 所在的文件夹,每一个 变体 Variants 实际代表的是这个 APK 文件所在的文件夹,按图中理解,Variants 就是 debug、release
这2个文件夹
2. 变体的维度
Android 插件设计 Variants 时设计了3个维度:
dimension
flavor
buildType
这样理解:
dimension:
渠道分级,dimension 级别最高flavor:
渠道,flavor 级别次之buildType:
构建类型,级别最低
最终的 Variant.name = flavor + buildType,不过这里 flavor 取的是 不同 dimension 的 flavor 之间笛卡尔集,看图:
理解重点是:不同 dimension 分组之间的 flavor 交叉取集 笛卡尔集
dimension
和 flavor
这2个级别可以不用,写不写全看你
在这里废了不少时间,网上资料这里很多写的都不对,费大事了
3. DSL 编写
android {
flavorDimensions "xiaomi", "huawei"
productFlavors {
JD {
dimension("xiaomi")
}
TAO {
dimension("xiaomi")
}
PIN {
dimension("huawei")
}
}
buildTypes {
release{}
vip{}
}
}
4. 主项目和子项目 buildTypes 必须同步
从 android 3.0 版插件开始,主项目和子项目之间的 buildTypes 必须一样,除了默认的 debug、release
之外,主项目多写一个 buildType,子项目也必须有这个 buildType 才行,要不报错
// app module
buildTypes {
release {}
vip{}
}
// libs module
buildTypes {
vip{}
}
这样才能过,如果不想每个子项目都写的话,可以这样,把多出来的 buildType 写到基类 gradle 脚本中,每个项目继承这个基类脚本就行了
// base_gradle.gradle
android {
buildTypes {
pay {}
}
}
// app module
apply from: rootProject.file("base_gradle.gradle")
// libs module
apply from: rootProject.file("base_gradle.gradle")
5. 过滤变体
有的变体我们不想打出来,我们可以过滤他
没有自动提示真蛋疼,这段我没跑过去,我也不知道哪拼错了,我这 VPN 被封了没法翻墙看 Android 插件文档,蛋疼,大家都想办法配一个 VPN 吧,有好使的 VPN 评论通知我一声,我也去搞一个
android{
variantFilter{ variant ->
if (variant.buildType.name.equals("release") ){
variant.productFlavors.each{ flavor ->
if (flavor.name.equals("PIN")){
variant.ignore = true
}
}
}
}
}
6. 修改 apk 文件名
Android Gradle 插件提供了3个属性,applicationVariants(适用于Android 应用Gradle插件),libraryVariants(适用于Android库gradle插件),testVariants(以上两种都适用)
applicationVariants 是一个集合,内部元素是一个个 Variants 变体,就是 xxxRelease、xxxDebug 这些,而每一个 Variants 变体的输出物不仅仅只有 apk 文件,还有其他一些文件,所以 variant.outputs 也是一个集合,要修改 APK 名称的话,我们淂多一道手,判断是不是 APK 文件
applicationVariants 是 android 插件提供的设置,必须写在 android{...} DSL 里面,一般我们都是写在 app module 的脚本里
def buildTimes() {
return new Date().format("yyyyMMdd")
}
applicationVariants.all { variant ->
variant.outputs.all { output ->
if (output.outputFile == null && !output.outputFile.name.endsWith('.apk')) {
contiue
}
def info = ""
// 因为维度存在,所以一个 variant 可能由有一个以上的 Flavor 交叉组成,所以这里 Flavor 名也是复数的
variant.productFlavors.each{
info = info + it.name + "_"
}
println("TAG:${variant.name}/${info}")
outputFileName = ${info}${variant.buildType.name}_v${variant.versionCode}_${buildTimes()}.apk"
}
上面这点代码本身不复杂,就是2层遍历,但是蛋疼的是,AS 没有自动提示,DSL 这种语法糖也不提示参数类型,这叫我们怎么写呀,点进去看看有啥参数都找不到地方
Gradle 与组件化的结合
一般的就不说了,写几个常用的,有意思的,其他的设置可以参考下面:
- 管理我们的 gradle 依赖
- Android动态配置ApplicationId,App名字,AppLogo
- 这个有点老,先参考下面这个
- Android Gradle多渠道打包的实现方法
- Gradle系列(三) Gradle配置构建和渠道包
- 不同渠道包折腾来回折腾文件夹可以看这个后面的内容
1. 测试、发版时切换 BaseUrl
buildTypes {
debug{
buildConfigField( 'String','baseUrl','"baseUrl_debug"' )
}
release {
buildConfigField( 'String','baseUrl','"baseUrl_release"' )
}
}
2. flavor引用不同的module
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// 引用本的项目
devImplementation project(':devModule')
stageImplementation project(':stageModule')
prodImplementation project(':prodModule')
// 也可以分渠道引用网络的。因为这里都相同,所以地址也就都一样了
devImplementation 'com.roughike:bottom-bar:2.0.2'
stageImplementation 'com.roughike:bottom-bar:2.0.2'
prodImplementation 'com.roughike:bottom-bar:2.0.2'
}