什么是buildTypes和productFlavors
https://developer.android.com/build/build-variants?hl=zh-cn
1. buildTypes
buildTypes
主要用于定义不同的构建变体,通常用于区分不同的构建模式,如开发版、发布版等。每个 buildType
都会有一组配置项,通常是与构建过程和构建输出相关的配置。常见的 buildTypes
包括:
debug
:用于调试构建,通常包含日志和调试功能。release
:用于发布构建,通常会启用混淆、签名、优化等。
一共这些方法
https://developer.android.com/reference/tools/gradle-api/8.7/com/android/build/api/dsl/BuildType
buildTypes
定义的是构建过程的行为,它影响的是最终的 APK 构建方式,例如签名方式、混淆规则等。
android {
buildTypes {
debug {
minifyEnabled false // 不启用混淆
debuggable true
}
release {
minifyEnabled true // 启用混淆
shrinkResources true // 去除未使用的资源
signingConfig signingConfigs.release
}
}
}
2. productFlavors
productFlavors
用于定义不同的产品变体,通常是用来支持不同的产品版本或配置,比如免费版和付费版、不同地区的版本等。通过 productFlavors
,你可以为不同的版本提供不同的代码、资源或配置。
productFlavors
允许你在同一个项目中创建多个产品变体,每个变体可以有不同的资源、应用 ID、版本号等。
android {
flavorDimensions "version"
productFlavors {
free {
applicationId "com.example.app.free"
versionName "1.0-free"
}
paid {
applicationId "com.example.app.paid"
versionName "1.0-paid"
}
}
}
区别总结:
buildTypes
控制构建过程的行为(如是否启用混淆、签名、调试信息等),默认有debug
和release
两种常见类型。productFlavors
控制应用的版本和特性(如免费版、付费版、不同地区版本等),让你可以为不同的目标配置不同的资源和代码。
在安卓开发过程中,难免会遇到像以下这样的一些需求:
1.需要打不同市场的包像opp vivo等,用于友盟统计各个市场的下载量
2.需要打测试包,生产包等,要求每个报名下的app名称,应用图标,appid ,url不同,甚至代码
像以上的一些需求我们称之为Android的差异化打包
现在我们一起来配置,下面的图是我配置好的
productFlavors{
//todo a ,b,c,d等是打包提供的一些标志名称,打包的时候可以选择
a{
applicationId "com.example.myapplication1"
resValue "string", "app_name", "测试a"
buildConfigField 'String', 'BASE_URL', '"我时a 的路由"'
manifestPlaceholders=[
APPICON : "@mipmap/ic_launcher",
]
}
b{
applicationId "com.example.myapplication2"
resValue "string", "app_name", "测试b"
buildConfigField 'String', 'BASE_URL', '"我时b 的路由"'
manifestPlaceholders=[
APPICON : "@mipmap/down",
]
}
c{
applicationId "com.example.myapplication3"
resValue "string", "app_name", "测试c"
buildConfigField 'String', 'BASE_URL', '"我时c 的路由"'
manifestPlaceholders=[
APPICON : "@mipmap/up",
]
}
d{
applicationId "com.example.myapplication4" //修改application
resValue "String", "app_name", "测试d" //todo 修改res中的资源
buildConfigField 'String', 'BASE_URL', '"我时d 的路由"' //todo 用来根据不同的包,更换不同的utl
manifestPlaceholders=[
APPICON : "@mipmap/app_icon_mail", //todo 清单文件中映射的值
]
}
}
然后运行的时候运行和打包的时候可以选择,这里以运行为列,点击如下按钮,可以选择当前运行包的环境
介绍完productFlavors 后,我们现在带着问题来解释下他的一些属性和用法
问题1:
manifestPlaceholders 占位符的使用,其实很好理解,你可以认为它可以在build.gradle
文件中定义字符串并将值映射到AndroidManifest
清单文件的指定位置.
如何使用呢?
首先在AndroidManifest中设置需要替代的字段
然后在build.gradle中设置清单文件中替代文字需要映射的值
d{
manifestPlaceholders=[
APPICON : "@mipmap/app_icon_mail", //todo 清单文件中映射的值
]
}
问题2:
resValue 这个指定后,会在build完成后,会在build文件里面生成值,例如
resValue "String", "app_name", "测试a" //他会在build文件夹生成如下
<string name="app_name" translatable="false">测试b</string>
如果你本里的values文件夹下存在了该
<string name="app_name">ExpandedRecycleViewDemo</string>
那么程序则会报错,因为build时会存在两个app_name的name
buildConfigField 这个属性很好用,这个属性在build后会生成一个buildConfig.java的文件里面有许多可以使用的信息,因此我们可以把BASEURL设置在此,我的是如下配置
d{
applicationId "com.example.myapplication4" //修改application
resValue "String", "app_name", "测试d" //todo 修改res中的资源
buildConfigField 'String', 'BASE_URL', '"我时d 的路由"' //todo 用来根据不同的包,更换不同的utl
manifestPlaceholders=[
APPICON : "@mipmap/app_icon_mail", //todo 清单文件中映射的值
]
}
接下来看下buildConfig的文件
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.example.myapplication2";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "b";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
// Fields from product flavor: b
public static final String BASE_URL = "我时b 的路由";
}
变生成了我设置的baseURL ,
以后就可以根据不同的打包环境生成不同的BASEURL
使用变体感知型依赖项管理机制 (这里指的是module ,不是线上的依赖库)
Android Gradle 插件 3.0.0 及更高版本包含一种新的依赖项机制,该机制可在使用库时自动匹配变体。这意味着,应用的 debug
变体会自动使用库的 debug
变体,依此类推。这种机制在使用变种时也同样适用:应用的 freeDebug
变体将使用库的 freeDebug
变体。
为了让插件准确匹配变体,您需要在无法进行直接匹配的情况下,按照以下部分中所述提供匹配回退机制。
例如,假设您的应用配置了一个名为“staging”的 build 类型,但该应用的一个库依赖项没有进行相应配置。当插件尝试构建“staging”版本的应用时,它不知道要使用哪个版本的库,因此您将看到一条与以下内容类似的错误消息
Error:Failed to resolve: Could not resolve project :mylibrary. Required by: project :app
解决与变体匹配相关的构建错误 :
您的应用包含库依赖项不包含的 build 类型。
例如,您的应用包含“staging”build 类型,但依赖项仅包含“debug”和“release”build 类型。
请注意,如果库依赖项包含您的应用不包含的 build 类型,这不会引发问题。这是因为,插件在任何时候都不会从依赖项请求该 build 类型。
使用 matchingFallbacks
为给定的 build 类型指定替代匹配项,如下所示:
app模块
buildTypes {
register("benchmark") {
isMinifyEnabled = true
signingConfig = signingConfigs.getByName("release")
proguardFiles(
getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
)
multiDexKeepProguard = file("multidex-rules.pro")
matchingFallbacks += listOf("debug", "release")
}
release {
isMinifyEnabled = true
isShrinkResources = true
// isDebuggable = true
signingConfig = signingConfigs.getByName("release")
proguardFiles(
getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
)
multiDexKeepProguard = file("multidex-rules.pro")
}
debug {
// buildConfigField("boolean","name","2")
isMinifyEnabled = true
applicationIdSuffix = ".debug" // 调试版应用 ID 后缀
signingConfig = signingConfigs.getByName("release")
proguardFiles(
getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
)
multiDexKeepProguard = file("multidex-rules.pro")
}
create("pre") {
// buildConfigField("boolean","name","1")
isDebuggable = true
}
}
module模块
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
module模块的buildTyp比 app少了benchmark
所以选择benchmark编译的时候会报错,
这个时候在app下添加,就行
matchingFallbacks += listOf("debug", "release")。// 选择benchmark模块的时候,其他module没有benchmark,则从listOf("debug", "release")集合中取,优先debug