日常开发中,不管在APP的Module或者Library的Module中
- 1、引入一些共用三方库
- 2、共有的编译库,比如compileSdkVersion,都是各自为政,没有做一个统一的管理
现在我们新建一个config.gradle文件来存储一些共有的部分。
一、config.gradle的创建使用
我们直接将我测试的config.gradle文件新建出来,如下代码,下面来慢慢解释
// 添加多个自定义属性,可以添加在ext代码块
ext {
username = "zhangsan"
// 生产开发环境(正式/测试)
// 定义一个项目全局变量isRelease,用于动态切换:组件化模式 / 集成化模式
// false: 组件化模式(子模块可以独立运行),true :集成化模式(打包整个项目apk,子模块不可独立运行)
isRelease = false
// 建立Map存储,对象名,key都可以自定义
androidId = [
compileSdkVersion: 29,
buildToolsVersion: "29.0.2",
minSdkVersion : 19,
targetSdkVersion : 29,
versionCode : 1,
versionName : "1.0",
]
appId = [
applicationId: "com.dh.summarize",
]
// 生产/开发环境的url
url = [
"debug" : "https://192.168.1.160/debug",
"release": "https://192.168.1.160/release"
]
// 第三方库
dependencies = [
"junit" : "junit:junit:4.12",
"runner" : "androidx.test:runner:1.3.0",
"espressoCore" : "androidx.test.espresso:espresso-core:3.3.0",
"appcompat" : "androidx.appcompat:appcompat:1.2.0",
"constraintlayout" : "androidx.constraintlayout:constraintlayout:2.0.1",
"supportAnnotations" : "com.android.support:support-annotations:28.0.0",
"lifecycleExtensions": "androidx.lifecycle:lifecycle-extensions:2.2.0",
// 使用Navigation需要导入的库
"navigationFragment" : "androidx.navigation:navigation-fragment:2.3.0",
"navigationUi" : "androidx.navigation:navigation-ui:2.3.0",
"legacySupportV4" : "androidx.legacy:legacy-support-v4:1.0.0",
]
}
(一)首先需要将自定义属性定义在ext代码块中
1、可以在ext代码块中定义变量,比如userName = "张三"等等
// 添加多个自定义属性,可以添加在ext代码块
ext {
userName = "zhangsan"
}
2、可以在其中定义键值对的属性(Map)
ext {
androidId = [
compileSdkVersion: 29,
buildToolsVersion: "29.0.2",
minSdkVersion : 19,
targetSdkVersion : 29,
versionCode : 1,
versionName : "1.0",
]
}
这其中可以随便定义你想定义的所有属性,上面的文件只是提供一个参考
二、在Project的build.gradle文件中引入confit.gradle文件,方便其他Project中其他Module使用
// 根目录下的build.gradle加入config.gradle,相当于在layout布局文件中加入include
apply from: "config.gradle"
三、开始使用config.gradle中的属性
在项目中其他Module的build.gradle文件中开始使用
1、比如上述的userName 属性的使用
完整使用userName属性的语法:
// 通过${rootProject.ext.username}这种方式来使用定义的变量
println "${rootProject.ext.username}"
简写:
// 因为config.gradle文件已经被引入到Project中,可以直接使用
println "${username}"
弱类型语言Groovy(糖果语法),定义的是String,也可以赋值为int,它会自动推导
例如:
rootProject.ext.username = 12345
// 输出的结果是 12345
println "${rootProject.ext.username}"
2、定义的键值对属性的使用
- 首先将键值对属性Map取出来(有点像new一个对象),语法如下
// 赋值与引用
def androidId = rootProject.ext.androidId
def appId = rootProject.ext.appId
def support = rootProject.ext.dependencies
def url = rootProject.ext.url
def isRelease = rootProject.ext.isRelease
- 然后使用Map对象取出其中的值使用如下
android {
// 通过androidId对象取出compileSdkVersion代表的属性值
compileSdkVersion androidId.compileSdkVersion
buildToolsVersion androidId.buildToolsVersion
defaultConfig {
applicationId appId.applicationId
minSdkVersion androidId.minSdkVersion
targetSdkVersion androidId.targetSdkVersion
versionCode 1
versionName "1.0"
// 开启分包(将apk分成多个dex)
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}
- 引入三方库文件
1、首先看日常经常看到的引入三方库方式,其实是简写
// 如下引用其实是简写
implementation 'androidx.appcompat:appcompat:1.2.0'
2、再次我们来看如果不简写,标准的写法(组+三方库名+版本号)
// 标准写法,组 三方库名 版本号
implementation group: 'androidx.appcompat', name: 'appcompat', version: '1.2.0'
3、从config.gradle文件中拿出定义的库属性
implementation support.appcompat
3.1、然后来看最简洁的引入定义在config.gradle中的第三方库
(定义了哪些第三方库,请看最上方的config.gradle文件)
// Map的遍历,最简洁的写法
support.each { k, v -> implementation v }
这种方式是最简洁的,看着也是最舒服的,O(∩_∩)O哈哈~,直接遍历集合
四、接下来看看其他常用用法
- 使用so库的时候cpu架构配置
// 配置so库的cpu架构(真机:arm(英国arm的架构) 模拟器:x86(intel的架构))
// x86 x86_64 mips mips64
ndk {
// abiFilters("armeabi-v7a")
abiFilters('armeabi-v7a', 'armeabi')
}
- 保留指定资源
// 只保留指定和默认资源
// resConfigs('zh-rCN')
resConfigs "zh", "en"
- 将svg图片生成指定维度的png图片
// 将svg图片生成指定维度的png图片
// vectorDrawables.generatedDensities('xhdpi', 'xxhdpi')
- buildConfigField字段的配置,配置的这个字段会生成在如下截图的文件路径中
接下来,我们看如何在gradle中配置这个属性
1、这个方法接收三个非空的参数,第一个:确定值的类型,第二个:指定key的名字,第三个:传值(必须是String)
2、为什么需要定义这个?
因为src代码中有可能需要用到跨模块交互,如果是组件化模块显然不行
3、切记:不能在android根节点,只能在defaultConfig或buildTypes节点下
使用代码如下,两种方式都在下方代码
// 第一种,在defaultConfig中定义
defaultConfig {
buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
}
// 第二种,在buildTypes中定义
buildTypes {
debug {
// signingConfig signingConfigs.debug
// 将属性编译到 BuildConfig.java中
buildConfigField("String", "debugUrl", "\"${url.debug}\"")
}
}
- 配置打包的apk的名字
//获取时间格式
static def releaseTime() {
return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC"))
}
// 配置打包的包名
android.applicationVariants.all { variant ->
variant.outputs.all {
//outputFileName = "app-${variant.name}-${variant.versionName}-${variant.baseName}.apk"
//app-baidu-debug-1.0.apk
outputFileName = "app-${variant.baseName}-${variant.versionName}-${releaseTime()}.apk"
}
}
- 设置不同的打包方式需要将哪些文件打包到apk中
// 源集 -- 设置源集的属性,更改源集的JAVA目录或者自由目录
sourceSets {
main {
if (!isRelease) {
// 如果是组件化模式,需要单独运行时
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java']
res.srcDirs = ['src/main/res']
resources.srcDirs = ['src/main/resources']
aidl.srcDirs = ['src/main/aidl']
assets.srcDirs = ['src/main/assets']
} else {
// 集成化模式,整个项目打包
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
- 通过gradle引入签名文件,然后gradle命令打包的时候,就会直接使用配置的签名文件
1、可以直接在Project的gradle.properties文件中添加签名文件的配置
2、也可以单独在Project的同级目录创建一个keystore.properties文件
我们此处使用第二种方式
1、创建keystore.properties文件,在文件中添加如下配置
# 签名文件路径,我这里是放在App Module中,所以跟app的build.gradle是同级目录,可以像如下这么引入
keyStoreFile=xxx.jks
#签名证书密码
keyStorePassword=12345678
#签名证书中秘钥别名(创建证书的时候就会让创建别名)
keyAlias=xxx
#签名证书中秘钥密码
keyPassword=12345678
2、在App Module中引入
2.1、首先获取签名文件
//获取签名属性文件,通过属性对象获取文件中的信息
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
2.2、配置签名文件
// 配置签名,必须写在buildTypes之前
signingConfigs {
/*debug {
storeFile file('磁盘中.android目录下的debug.keystore')
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}*/
release {
// 签名证书文件
storeFile file(keystoreProperties['keyStoreFile'])
// 签名文件类型
// storeType ""
// 签名证书文件的密码
storePassword keystoreProperties['keyStorePassword']
// 签名证书中秘钥别名
keyAlias keystoreProperties['keyAlias']
// 签名证书中秘钥密码
keyPassword keystoreProperties['keyPassword']
// 是否开启V1、V2打包
v1SigningEnabled = true
v2SigningEnabled = true
}
}
后续会继续更新其他使用