String compileDate = new SimpleDateFormat("yyyyMMddHHmm").format(new Date(System.currentTimeMillis()))
android {
applicationVariants.all { variant ->
variant.outputs.all { output ->
def apkName = 'Union_' + compileDate
outputFileName = apkName + '_' + variant.buildType.name + '.apk'
}
}
}
gradle 官网
https://docs.gradle.org/current/userguide/gradle_wrapper.html
gradle目录结构:
可以看出,每次启动gradle都启动了一个Daemon,daeman是用来执行compiler java的。如果daeman已经启动,则再次启动
只需要连接此daeman就可以了。所以第一次耗时比较久,冷启动,后面都是热启动,耗时少。
第一次:
Starting Gradle Daemon...
Gradle Daemon started in 9 s 133 ms
> Configure project :Test
configure
BUILD SUCCESSFUL in 28s
第二次:
Executing tasks: [:Test:assembleDebug] in project D:\work\LinkEverything
> Configure project :Test
configure
groovy in action 2
Gradle scripts下面主要是工程的编译配置文件,主要有:
1)Bulid.gradle 该文件分为项目级和模块级两种,用于描述App工程的编译规则。
2)Proguard-rules.pro 该文件用于描述java代码的混淆规则。
3)Gradle.properties,该文件用于配置编译工程的命令行参数,一般无须改动。
4)Settings.gradle, 该文件主要配置了需要编译那些模块。初始内容为include ‘:app’,表示只编译app模块。
5)Local.properties,项目的本地配置文件,他在工程编译时自动生成,用于描述开发者电脑的环境配置,包括Sdk的本地路径,Ndk的本地路径等。
6)Gradle中的编译语言为groovy。
工程build.gradle
采用阿里的仓库。
pluginManagement {
repositories {
maven { url'https://maven.aliyun.com/repository/public/' }
maven { url'https://maven.aliyun.com/repository/google/' }
maven { url'https://maven.aliyun.com/repository/jcenter/' }
maven { url'https://maven.aliyun.com/repository/central/'}
mavenLocal()
mavenCentral()
maven {
url 'https://jitpack.io'
}
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven { url'https://maven.aliyun.com/repository/public/' }
maven { url'https://maven.aliyun.com/repository/google/' }
maven { url'https://maven.aliyun.com/repository/jcenter/' }
maven { url'https://maven.aliyun.com/repository/central/'}
mavenLocal()
mavenCentral()
maven {
url 'https://jitpack.io'
}
}
}
buildscript {
repositories {
// google()
// jcenter()
maven {
url 'https://maven.aliyun.com/repository/google/'
}
maven {
url 'https://maven.aliyun.com/repository/public/'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
// google()
// jcenter()
maven {
url 'https://maven.aliyun.com/repository/google/'
}
maven {
url 'https://maven.aliyun.com/repository/public/'
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
模块build.gradle
plugins {
id 'com.android.application'
}
android {
// 指定编译用的SDK版本号。比如30表示Android11.0编译
compileSdkVersion 32
// 指定编译工具的版本号。这里的头两位数字必须与compileSdkVersion保持一致,
// 具体的版本号可在sdk安装目录的”sdk\build-tools“下找到
buildToolsVersion "32.0.0"
defaultConfig {
// 指定该模块的应用编号,也就是app的包名 应用编号需要和AndroidManifest中package相同
applicationId "com.example.myapplication"
// 指定App适合运行的最小SDK版本号。
minSdk 21
// 指定目标设备的SDK版本号
targetSdk 32
// 指定App的应用版本号
versionCode 1
// 指定App的应用版本名称
versionName "1.0"
// 测试类
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
// 代码混淆的混淆规则
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// android的兼容性问题 官方帮忙做好了android的向下适配
// 指定编译Android的高版本支持库。如AppCompatActivity必须指定appcompat库
// appcompat库各版本可以见 https://mvnrepository.com/artifact/androidx.appcompat/appcompat
implementation 'androidx.appcompat:appcompat:1.3.0'
// 指定单元测试用的junit版本号
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.constraintlayout:constraintlayout-core:1.0.0-beta03'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
// 任务,删除所有的build文件
task clean(type: Delete) {
delete rootProject.buildDir
}
gradle.beforeProject {project ->
println "123123 beforeProject: $project.name"
// 可以在生命周期内,触发我们自己写的插件
}
// groovy 语法 java严谨语法 groovy糖果语法
// 1. 字符串的拼接
// 2. list集合 map集合 方法 对象 闭包 任务 文件操作
// 操作一个字符串
task stringTest {
def str1 = "abcde"
def str2 = "feg"
println str1 + str2
println "${str1} ----- ${str2}"
}
task list {
def list = [1, 2, 3, 4, 5]
println list[0]
// 奇特方式之1
for (int i in list) {
println list[i]
}
// 奇特方式之2
for (i in 0..5) {
println list[i]
}
// 奇特方式之3,it就表示this ,这里就是每一个元素
list.each {
println it
}
}
task map {
/**
*{'key':'name','value':'andy'}*{'key':'age','value':18}*/
def map = ['name': 'andy', 'age': 18]
println map['name']
map.each {
println "Key:${it.key} ---- Valye:${it.value}"
}
}
task method {
def a = methodA(3, 5)
println a
}
def methodA(int a, int b) {
// groovy 语法 默认将函数的最后一行(非空)作为结果进行返回
a + b
println 22222
}
task testStudent {
Student student = new Student()
student.name = "jjworld"
student.age = 18
println "age: ${student.age}"
}
class Student {
String name
int age
String getName() {
return name
}
void setName(String name) {
this.name = name
}
}
// 闭包类似于java中的interface,类似于前端的callback,钩子
// 闭包只针对特定区域有效,只针对大括号中有效{}
task closure {
mEach {
println it
}
mEachWithParams { m, n ->
println "${m} is ${n}"
}
}
def mEach(closure) {
for (int i in 1..5) {
closure(i)
}
}
def mEachWithParams(closure) {
def map = ["name": 'groovy', 'age': 10]
map.each {
closure(it.key, it.value)
}
}
结果
abcdefeg
abcde ----- feg
1
2
3
4
5
null
1
2
3
4
5
null
1
2
3
4
5
andy
Key:name ---- Valye:andy
Key:age ---- Valye:18
22222
null
age: 18
1
2
3
4
5
name is groovy
age is 10
ִ�н�ִ�����...
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField "boolean", "OVERSEAS", "true"
println getUrlPath("release")
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField "boolean", "OVERSEAS", "true"
println getUrlPath("debug")
}
def getUrlPath(String path) {
def url
Properties properties = new Properties()
def proFile = file('src/main/filters/' + path + '/config.properties')
if (proFile.canRead()){
properties.load(new FileInputStream(proFile))
if (properties != null){
url = properties.get("url")
}
}
url
}
"www.321.com"
"www.123.com"
使用productFlavors
flavorDimensions "default"
productFlavors{
domestic {
dimension "default"
buildConfigField("boolean","OVERSEAS","false")
}
overseas {
dimension "default"
buildConfigField("boolean","OVERSEAS","true")
}
}
gradle介绍多项目打包参考
https://lippiouyang.gitbooks.io/gradle-in-action-cn/content/multi-project/module-project.html
在 Android 的 build.gradle 文件中,sourceSets 属性用于定义项目的源代码集合。它指定了项目的源代码目录和资源目录。
sourceSets 属性的主要作用有:
1、定义源代码目录:可以通过 sourceSets 属性来指定项目的源代码目录。默认情况下,Android 项目的源代码目录是 src/main/java,可以通过 sourceSets.main.java.srcDirs 属性来修改。
2、定义资源目录:可以通过 sourceSets 属性来指定项目的资源目录。默认情况下,Android 项目的资源目录是 src/main/res,可以通过 sourceSets.main.res.srcDirs 属性来修改。
3、自定义源代码目录和资源目录:可以通过 sourceSets 属性来定义自定义的源代码目录和资源目录。例如,可以通过 sourceSets.create(“custom”) 来创建一个名为 “custom” 的源代码集合,并通过 sourceSets.custom.java.srcDirs 和 sourceSets.custom.res.srcDirs 属性来指定该集合的源代码目录和资源目录。
4、配置源代码和资源目录的属性:可以通过 sourceSets 属性来配置源代码和资源目录的属性,例如编译选项、依赖关系等。例如,可以通过 sourceSets.main.java.srcDirs 和 sourceSets.main.res.srcDirs 属性来配置源代码和资源目录的编译选项。
sourcesets.main.jnilibs.srcdirs 是一个 Gradle 构建脚本中的属性,用于指定 JNI 库的源代码目录。在 Android 项目中,JNI(Java Native Interface)库用于在 Java 代码中调用本地(C/C++)代码。
在 Gradle 构建脚本中,可以通过设置 sourcesets.main.jnilibs.srcdirs 属性来指定 JNI 库的源代码目录。通常,这个属性的默认值是 “src/main/jniLibs”,即在项目的主目录下的 “src/main/jniLibs” 目录中查找 JNI 库的源代码。
以下是一个示例的 Gradle 构建脚本,演示如何使用 sourcesets.main.jnilibs.srcdirs 属性:
android {
// ...
sourceSets {
main {
jniLibs.srcDirs = ['src/main/customJniLibs']
}
}
// ...
}
在上面的示例中,我们将 sourcesets.main.jnilibs.srcdirs 设置为 “src/main/customJniLibs”,这意味着 Gradle 将在项目的主目录下的 “src/main/customJniLibs” 目录中查找 JNI 库的源代码。
在Android Studio中,repositories.flatDir.dirs是一个Gradle属性,用于指定项目中本地存储库的目录。通过在build.gradle文件中设置这个属性,可以告诉Gradle在指定的目录中搜索本地存储库的依赖项。
例如,如果你的项目中有一个本地存储库的目录是"libs",你可以在build.gradle文件中添加以下代码:
repositories {
flatDir {
dirs 'libs'
}
}
然后,Gradle将会在"libs"目录中搜索本地存储库的依赖项。这些本地存储库的依赖项可以通过在dependencies部分中添加以下代码来引用:
dependencies {
implementation name: 'libraryName'
}
这里的’libraryName’是你想引用的本地存储库的名称。