Gradle

Hilt 是 Android 专属的依赖注入 (Dependency Injection, DI) 库,它建立在著名的 Dagger 库之上,旨在简化 Dagger 在 Android 应用中的使用。它通过提供一套标准的组件和作用域,并自动生成和管理它们所需的模板代码,让开发者更容易地实现依赖注入。

1、Gradle wrapper

gradle的包装器,是对Gradle的一层包装,能够指定Gradle的版本。
a. 项目根目录的gradle文件夹存放了wrapper信息
gadle-wrapper.jar: 包含Gradle运行时的逻辑代码。
gradle-wrapper.properties: 负责配置包装器运行时行为的属性文件,用来配置使用哪个版本的Gradle等属性。

gradlew: 在linux平台下,用于执行Gradle命令的包装器脚本。
gradlew.bat 在windows平台下,用于执行gradle 命令的包装器脚本。
b. gradle-wrapper.properties 文件内容
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

distributionBase:gradle解包后存储的主目录。
distributionUrl:gradle发行版压缩包的下载地址,-bin发行版只包含运行时,但不包含源码和文档。-all包含所有。
distributionPath: distributionBase指定目录的子目录。
zipStoreBase: gradle压缩包存储的主目录。
zipStorePath: zipStoreBase指定目录的子目录。
c. 使用gradle wrapper
不是用gradle命令,而是用gradlew和gradlew.bat脚本。

在build.gradle中加入如下语句

task test{
	doLast{
		println 'Hello World!'
	}
}

在项目根目录执行 gradlew.bat test 将会输出

> Task: test
Hello world!

d. 升级Gradle Wrapper
升级Gralde有两种方式,一直是设置gradle 属性文件的distributionUrl属性,第二种方式是运行wrapper任务,推荐使用第二种方式
例如:
> gradlew wrapper --gradle-version 5.5.1

其他命令
--distribution-type:指定下载gradle发行版的类型,可用选项有bin或者all。
--gradle-distribution-url: 指定下载Gradle发现版的完整URL地址。
--gradle-distribution-sha256-sum: 使用的SHA-256散列和验证下载的Gradle发行版。    
e. 自定义Gradle wrapper
Gradle已经内置了Wrapper task,因此构建gradle wrapper会生产gradle wrapper的属性文件,这个属性文件可以通过自定义wrapper task来设置。比如我们想要下载的gradle 版本修改为4.2.1。

task wrapper(type:Wrapper){
	gradleVersion = '4.2.1'
}

也可设置gradle发行版压缩包的网络下载地址和gradle解包后的本地存储路径等地址

task wrapper(type:Wrapper){
	gradleVersion = '4.2.1'
	distributionUrl = '../../gradle-4.2.1-bin.zip'
	distributionPath=wrapper/dists
}

2、Android中的Gradle插件


android{

	defaultConfig{
	
	}

	buildTypes{
	
	}
	
}

dependencies{

}


defaultConfig块常用的属性

属性 说明
applicationId 指定app的包名
miniSdkVersion App最低支持的SDK版本
targetSdkVersion 基于哪个SDK版本开发
versionCode App内部的版本号,用于控制App升级
versionName App版本名称,也就是发布的版本号
testApplicationId 配置测试app的包名
testInstrumentationRunner 配置单元测试使用的Runner,默认为android.test.Instrumentation.TestRunner
proguardFile ProGuard混淆所使用的ProGuard配置文件
proguardFiles 同时配置多个ProGuard配置文件
signingConfig 配置默认的签名信息
BuildType块用于配置构建不同类型的APK
release 和debug是默认配置,我们可以自定义构建类型

buildType{

	release{
	}
	debug{
	
	}
	privatedebug{ //自定义类型
	
	}}
}

buildType块常用属性

属性 说明
applicationIdSuffix 配置applicationID的后缀
debuggable 表示是否支持断电调试
jniDebuggale 表示是否可以调试NDK代码
buildConfigField 配置不同的开发环境,比如测试环境和正式环境
shrinkResources 是否自动清理未使用的资源,默认值为false
zipAlignEnabled 是否开启zipalign优化,提高apk的运行效率
proguardFile ProGuard混淆所使用的ProGuard配置文件
proguardFiles 同时配置多个ProGuard配置文件
signingConfig 配置默认的签名信息
multiDexEnabled 是否启动自动拆分多个Dex的功能

signingConfigs块 用于配置签名设置


signingConfigs{
	release{
	
	}

}

signingConfigs块常用属性

属性 说明
storeFile 签名证书文件
storePassword 签名证书文件的密码
storeType 签名证书的类型
keyAlias 签名证书中的密钥的别名
keyPassword 签名证书中的密钥的密码

其他配置块

属性 说明
sourceSets 配置目录指向
productFlavors 多个渠道配置
lintOptions Lint配置
dexOptions DEX工具配置
adbOptions adb配置
packageingOptions 打包时的相关配置
如果多个module的配置相同可以使用全局配置
全局配置一 使用ext块配置
在项目build.gradle中使用ext块    

ext{
	compileSdkVersion = 28
	buildToolsVersion = "28.0.3"
	minSdkVersion = 15
	targetSdkVersion = 28
}

在某个module的build.gradle中使用配置


apply plugin: 'com.android.application'
android{
	compileSdkVersion rootproject.ext.compileSdkVersion
}

全局配置二 使用Config.gradle配置
首先在根目录下创建config.gradle文件来进行配置
config.gradle    

ext{
	android=[
		applicationId : "com.example.app",
		compileSdkVersion :28,
		miniSdkVersion: 15
	]
	
	dependencies = [
		"appcompat-v7" : "com.android.support:appcompat-v7:28.0.0",
	
	]
}

最后在项目的build.gradle中添加


apply from: 'config.gradle'

这样项目的所有modle都能用config.gradle中定义的参数了


android{
	compileSdkVersion rootProject.ext.android.compileSdkVersion
	defaultConfig{
		application rootProject.ext.android.applicationId
	
	}

}

dependencies{
	implementation rootProject.ext.dependencies["appcompat-v7"]
	
}

dependencies块
用于配置该module构建过程中所依赖的库,Gradle插件3.4版本新增了api和implementation来代替compile配置依赖,其中api与compile是一样的。implementation和api主要有以下区别
implementation : 可以让module在编译时隐藏自己使用的依赖,但是在运行时这个依赖对所有模块式可见的,而api与comile一样,无法隐藏自己所使用的依赖。
api: 如果一个module发生变化,那么这条依赖链上的所有module都需要重新编译,而使用implementation只有直接依赖这个module需要重新编译。

3、Android签名文件的配置

本地添加签名信息文件
将签名文件放到~/.gradle/gradledemo.jks,签名信息文件放到~/.gradle/keystore.properties这样签名文件和签名信息都不会提交到GitHub

keystore.properties的内容如下所示

GRADLEDEMO_RELEASE_STORE_FILE = ~/.gradle/release-key.keystore
GRADLEDEMO_RELEASE_KEY_ALIAS=key-alias
GRADLEDEMO_RELEASE_STORE_PASSWORD=pass
GRADLEDEMO_RELEASE_KEY_PASSWORD=pass

在模块build.gradle中的signingconfigs块中配置签名信息

signingConfigs{

	release{
		storeFile file(GRADLEDEMO_RELEASE_STORE_FILE)
		storePassword GRADLEDEMO_RELEASE_STORE_PASSWORD
		keyAlias GRADLEDEMO_RELEASE_STORE_PASSWORD
		keyPassword GRADLEDEMO_RELEASE_KEY_PASSWORD
	
	}
}

4、Gradle的库依赖

引入libs下的所有jar

implementation fileTree(dir:'libs',include:['*.jar'])

指定依赖某一个或几个jar

implementation files('libs/xxx.jar','libs/yyy.jar')

arr依赖需要额外增加一些语句

android{

	repositories{
		flatDir{
			dir "libs"
		}
	}


}

dependencies{
	implementation fileTree(dir:'libs',include:['*.arr'])
	implementation(name:'xxx',ext:'arr')
	
}

Gradle本地module依赖
当项目中有多个Module时,我们需要先在settings.gradle中引入module    

include ':app'
include ':library1' , ':library2'

然后在模块build.gradle中引入

implementation project(':library1')

implementation group:'com.android.support',name:'appcompat-v7',version:'28.0.0.0'
简写
implementataion 'com.android.support:appcompat-v7:28.0.0'

依赖冲突
依赖传递
projectc依赖projectb,projectb依赖projecta,那么projectc就依赖projecta

依赖检查
1、在项目的根目录下 执行gradle :app:dependencies即可,会自动打印出依赖关系树
2、使用gradle面板,app->help->dependencies 双击执行
3、使用gradle view插件,File->Settings->Plugins ,搜索Gradle view找到gradle view并安装重启Android Studio,接下来依次选择View->Tools Window->Gradle View 这个时候就可以看到依赖关系了

解决方法一
依赖传递会产生一些问题,比如重复依赖,依赖错误等,我们可以通过transitive来禁止依赖传递

禁止某一个库的依赖传递,此库下面的依赖都不会继续向上传递    

implementation('com.xxx.xxx:xxx:1.1'){
	transitive false
}

关闭当前所有库的依赖传递

configurations.all{
	transitive = false
}

解决方法二
force 强制使用统一的库版本    

configurations.all{
	resolutionStrategy{
		force 'com.squareup.okio:okio:2.1.0'
	}
}

depedencies{
	
}

解决方法三
exclude排除库依赖传递中设计的库    

configurations{
	all*.exlude group: 'com.android.support', module: 'support-annotations'

}

dependencies{
	...
}

使用依赖检查来查看com.android.support:appcompat-v7:28.0.0可以发现不在依赖 com.android.support:support-annotations:28.0.0

5、libs.versions.toml版本清单



[versions]
runtime = "1.9.0"

[libraries]
androidx-runtime = { group = "androidx.compose.runtime", name = "runtime", version.ref = "runtime" }

1、最直接的写法,写死版本号。
androidx-runtime = { group = "androidx.compose.runtime", name = "runtime", version.ref = "1.9.0" }

2、version.ref 引用统一定义的版本。
androidx-runtime = { group = "androidx.compose.runtime", name = "runtime", version.ref = "runtime" }
👉好处:如果多个依赖用同一个版本,只需要在 [versions] 里改一次。

3、version.strictly 强制依赖必须是这个版本,不允许被传递依赖升级/降级。
androidx-runtime = { group = "androidx.compose.runtime", name = "runtime", version.strictly = "1.9.0" }
👉 任何传递依赖如果要求 1.2 或 1.0,都会被强制锁定在 1.9.0。

4、version.require 要求至少这个版本,但允许更高版本。
androidx-runtime = { group = "androidx.compose.runtime", name = "runtime", version.strictly = "1.9.0" }
👉 如果别的依赖带来 1.9.1,则会用 1.9.1,但不会低于 1.9.0。

5、version.prefer 偏好使用某个版本,但允许传递依赖升级。
androidx-runtime = { group = "androidx.compose.runtime", name = "runtime", version.strictly = "1.9.0" }
👉 如果别的依赖要求 1.9.2,会用 1.9.2;但如果没人指定,就用 1.9。