目录
1、前言
2、flavorDimensions 的意义
3、productFlavors的意义
4、productFlavor
5、写在最后
html
有了前两篇博客的铺垫,咱们能够来分享下另外两个参数了 flavorDimensions
和 productFlavors
,而这两个参数成对出现,能够作一些差分化定义。java
前两篇博客为:
一、defaultConfig——安卓gradle
二、buildTypes——安卓gradle
android
须要事先说明的是,接下来所说的 “意义” 并不是官方文档翻译,而是结合了小盆友本身的理解,会比较口语化。git
flavorDimensions 从单词字面理解知道是 “风味维度”,是须要结合 “产品风味(即productFlavors)” 来一块儿使用的。程序员
flavorDimensions 的使用会定义出维度,供接下来的 productFlavors 使用。咱们举个例子github
android {
// 省略其余参数
flavorDimensions('abi', 'version')
}
复制代码
使用上面代码,则会定义出两个维度:version 和 abi。一个参数一个维度,咱们把它形象化,就能够当作下面这样一张图。而他有什么做用,咱们看下一小节。 后端
若是三个参数就能够当作一个三维的空间坐标系,这里的坐标系只是一个形象化的体现。bash
productFlavors 从字面了解是“产品风味”。他须要和一个风味维度对接,不然会报错。微信
接着咱们上面的例子,使用 productFlavors 定义维度上的风味,使用 dimension
关联。架构
android{
// 其余参数
flavorDimensions('abi', 'version')
// 建立产品风味
productFlavors {
v1 {
// 关联纬度
dimension 'version'
}
v2 {
dimension 'version'
}
v3 {
dimension 'version'
}
x86 {
dimension 'abi'
}
armV7 {
dimension 'abi'
}
}
}
复制代码
经过上面这段代码,会造成下面这张图。在 abi 维度上关联了两个产品,即 “armV7” 和 “x86”,在 version 的维度上关联了三个产品,即 “v1”、“v2” 和 “v3”。
咱们能够根据不一样的风味,打出不一样的apk包,即可以实现一套核心代码打出多个有些差别的包。
更多的使用咱们在下篇博客讲解,咱们先了解下他可配置的参数。
productFlavors
下的每一个项最终形式是 productFlavor
,即咱们上面说所的 “v1”,“v2”.....
咱们知道,每一个配置最终会被映射为一个类,或是一个属性、或一个方法。productFlavor 也不例外,他会被映射为 com.android.build.gradle.internal.dsl.ProductFlavor
,继承结构以下
咱们先来一个约定,避免使用的代码过于冗长。
android {
productFlavors{
zincPower{
// 咱们下面的 “使用方法” 代码都是基于这一块,除非特殊说明。
}
}
}
复制代码
defaultConfig
中配置的 applicationId
。从而可让咱们打出不一样的apk包。defaultConfig 的具体配置能够看小盆友的另外一篇博文,传送门。
zincPower {
// applicationId 应用的包名,会覆盖 defaultConfig 中的 applicationId
// applicationId 会替换 AndroidManifest.xml 中的 manifest 标签下 package 的 value
applicationId "com.zinc.power"
......省略其余配置
}
复制代码
zincPower {
applicationIdSuffix '.debug'
}
复制代码
library
中,包括咱们以aar形式导入的 library ,或是直接建立的 library。它的做用是,负责该 library 被进行编译时的混淆规则,咱们在 主App 的模块下则能够不用再管理各个 library 的混淆规则,会直接使用各个 library 的混淆规则文件。zincPower {
consumerProguardFiles 'consumer-rules.pro'
......省略其余配置
}
// 由于该属性是一个 List<File> 类型,若是须要多个文件配置,则以下所示
zincPower {
consumerProguardFiles 'consumer-rules.pro','zincPower-rules.pro'
......省略其余配置
}
复制代码
ERROR: Flavor 'v1' has no flavor dimension.
复制代码
zincPower {
// 关联纬度
dimension 'version'
......省略其余配置
}
复制代码
zincPower {
externalNativeBuild {
ndkBuild {
// Passes an optional argument to ndk-build.
arguments "NDK_MODULE_PATH+=../../third_party/modules"
}
// For ndk-build, instead use the ndkBuild block.
cmake {
// Passes optional arguments to CMake.
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
// Sets a flag to enable format macro constants for the C compiler.
cFlags "-D__STDC_FORMAT_MACROS"
// Sets optional flags for the C++ compiler.
cppFlags "-fexceptions", "-frtti"
// Specifies the library and executable targets from your CMake project
// that Gradle should build.
targets "libexample-one", "my-executible-demo"
}
}
}
复制代码
annotationProcessor
时所须要的参数。zincPower {
javaCompileOptions {
annotationProcessorOptions{
arguments = []
classNames ''
....
}
}
......省略其余配置
}
复制代码
JavaCompileOptions 能够配置的具体参数,请进传送门
AndroidManifest.xml
中替换的参数,咱们可使用这个参数配置不一样风味的 logo 和 app名字,以及友盟的参数,达到不一样风味的差别化配置。咱们配置差别化的 logo 和 app名字,则能够在 gradle 中使用下面这段
android {
flavorDimensions('abi', 'version')
productFlavors {
// 省略其余的风味配置
x86 {
dimension 'abi'
// 配置不一样的包名,达到能两个风味能共存
applicationId 'com.zinc.bear'
manifestPlaceholders = [
logo : "@drawable/logo_bear",
appName : "bear",
]
// 配置签名
signingConfig signingConfigs.jiangpengyong
}
armV7 {
dimension 'abi'
// 配置不一样的包名,达到能两个风味能共存
applicationId 'com.zinc.shark'
manifestPlaceholders = [
logo : "@drawable/logo_shark",
appName : "shark",
]
// 配置签名
signingConfig signingConfigs.xiaopenyou
}
}
}
复制代码
logo的资源图
而后在 AndroidManifest.xml
中使用,使用 ${你配置的变量名}
<application android:allowBackup="true" android:icon="${logo}" android:label="${appName}" android:roundIcon="${logo}" android:supportsRtl="true" android:theme="@style/AppTheme">
......
复制代码
最终分别运行后,咱们能够看到以下效果
举个例子: 咱们有一个 x86 的风味 在引入一个 library,而 library 中存在一样的风味维度,可是没有相同产品风味,这样会致使无法匹配,此时,就须要用这个参数。代码以下:
app 下的 build.gradle
android {
// 其余配置
flavorDimensions('abi')
// 建立产品风味
productFlavors {
x86 {
dimension 'abi'
matchingFallbacks = ['pro']
}
}
dependencies {
// 引入 flavor_x86 library
x86Implementation project(':flavor_x86')
}
复制代码
flavor_x86 下的 build.gradle
android {
// 存在相同的风味维度
flavorDimensions('abi')
// 没有相同的产品风味,须要使用 matchingFallbacks 选择须要的产品风味
productFlavors {
pro {
dimension 'abi'
}
free{
dimension 'abi'
}
}
}
复制代码
小盆友在github上有个demo,有所帮助就给star吧。
64K 引用限制问题官方文档 传送门
为了不篇幅过长,使用方法请看小盆友的另外一片博文:defaultConfig——安卓gradle 的 3.8小节
classs.dex
。咱们在第 2.9 小点,分享到使用了多 dex包处理,有时咱们须要将一些主要的类打包进主包,则可使用该属性。zincPower {
multiDexKeepFile file('multidex-config.txt')
...
}
复制代码
multidex-config.txt 中的书写则以下,每个文件则为一行
com/example/MyClass.class
com/example/TestClass.class
复制代码
zincPower {
multiDexKeepFile file('multidex-config.pro')
...
}
复制代码
multidex-config.pro 中的写法以下
// 将会保留全部的在com.example package的类
-keep class com.example.** { *; }
复制代码
armeabi-v7a
,不会包含其余的架构,例如 "X86"。zincPower {
// ndk中,目前只有 abiFilter 一个属性,因此 ndk 目前来讲只用于 abi 的过滤
ndk {
abiFilter 'armeabi-v7a'
}
...
}
复制代码
NdkOptions的具体可配参数见官方文档 传送门
minifyEnabled
设置为 true 的时候会使用这个参数,文件中须要申明哪些文件不被优化和混淆。zincPower {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
复制代码
SigningConfig 的可配置参数 传送门
(1)咱们须要先在项目根目录下建立一个 keystore.properties 文件,在文件中写入对应的配置,如图所示
// 引入咱们在(1)中建立的配置
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
compileSdkVersion 28
buildToolsVersion "29.0.1"
defaultConfig {
// 省略一些配置...
}
signingConfigs {
xiaopenyou {
// 使用 keystoreProperties 获取对应的参数
keyAlias keystoreProperties['keyAlias2']
keyPassword keystoreProperties['keyPassword2']
storeFile file(keystoreProperties['storeFile2'])
storePassword keystoreProperties['storePassword2']
}
// ...其余签名配置
}
buildTypes {
// 省略一些配置...
}
flavorDimensions('abi', 'version')
// 建立产品风味
productFlavors {
// 省略一些配置...
armV7 {
// 省略一些配置...
signingConfig signingConfigs.xiaopenyou
}
}
}
复制代码
generatedDensities
和 useSupportLibrary
。分别的用处以下zincPower {
vectorDrawables {
// 若是 minSdkVersion 小于 21,只生成mdpi的png
generatedDensities 'mdpi'
// 设置为 true,会忽略 generatedDensities ,会加入svg兼容包,不会再产生png
useSupportLibrary true
}
}
复制代码
矢量图的用法,能够看小盆友的另外一片文章
versionName
的区别在小盆友看来,versionCode
是给程序员看的,versionName
是给产品经理和用户看的。zincPower {
versionCode 1000
......
}
复制代码
zincPower {
versionName "1.0.0"
.....
}
复制代码
zincPower {
// 若是 versionName "1.0.0" ,则最终的版本名为 1.0.0.test
versionNameSuffix ".test"
.....
}
复制代码
// 值的注意的是 value 的值是原样放置,咱们经过使用方法一节来了解
<type> <name> = <value>
复制代码
productFlavors {
x86 {
// 能够经过 BuildConfig 进行获取
buildConfigField('String', 'name', '"XiaoPenYou"')
buildConfigField('int', 'age', '26')
.....
}
}
复制代码
最终会生成以下图的配置,咱们能够经过下面代码进行获取
String name = BuildConfig.name;
int age = BuildConfig.age;
复制代码
值的一提的是,咱们设置 String 类型的参数时,须要加上 "" 双引号(如例子中的name属性)。切记!
zincPower {
consumerProguardFile('consumer-rules.pro')
}
复制代码
zincPower {
consumerProguardFile('consumer-rules.pro', 'zincPower-rules.pro',.....)
}
复制代码
zincPower {
// 最高支持28版本
minSdkVersion 28
}
复制代码
zincPower {
// 最低支持19版本
minSdkVersion 19
}
复制代码
咱们的项目结构以下
zinclibrary
的
build.gradle
中编写了以下渠道配置
// 建立 风味维度
flavorDimensions('zinc', 'handsome')
// 建立产品风味
productFlavors {
minApi13{
dimension 'zinc'
}
minApi23{
dimension 'zinc'
}
x86{
dimension 'handsome'
}
arm64{
dimension 'handsome'
}
}
复制代码
此时若是直接在 app
的 build.gradle
中添加依赖,同步时便会出错
dependencies {
...忽略其余依赖
implementation project(":zinclibrary")
}
复制代码
因此咱们须要在 app
的 build.gradle
中使用这个参数进行忽略 library 中带来的维度和风味,即便用以下代码
zincPower {
missingDimensionStrategy 'zinc', 'minApi13', 'minApi23'
missingDimensionStrategy 'handsome', 'x86', 'arm64'
}
复制代码
zincPower {
proguardFile 'proguard-rules.pro'
}
复制代码
debug {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
复制代码
zincPower {
// 这样咱们编译出的apk中,只有 “默认” 和 “中文zh” 两种资源
resConfig "zh"
}
复制代码
zincPower {
// 这样咱们编译出的apk中,只有 “默认” 、 “中文zh” 和 “英文en” 两种资源
resConfigs "zh","en"
}
复制代码
zincPower {
// 添加至 res/value,经过 R.string.age 获取
resValue('string', 'age', '12year')
}
复制代码
zincPower {
consumerProguardFiles = [ 'consumer-rules.pro','zincPower-rules.pro' ]
}
复制代码
zincPower {
proguardFiles = [getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro']
}
复制代码
zincPower {
targetSdkVersion 28
}
复制代码
Gradle 的配置文件看起来好像挺乱,实际上是由于咱们没有进行总体的梳理,所谓 “无知最可怕”。
若是喜欢的话请给我一个赞,并关注我吧。文章中若有写的不妥的地方,请评论区或加我微信与我讨论吧,共同进步。
欢迎加我微信,进行更多的交流
若是以为文章有很大的帮助,快来赞扬一次吧😄