本篇博客是本人在学习Gradle过程中记录的笔记,目的是记录一些重点内容,方便以后的查阅以及学习。我们需要带着如下几个问题去学习Gradle
1.gradle是什么?
2.gradle是基于什么编程语言的?对它熟悉吗?
3.gradle能帮你做什么事情?
Gradle是一个开源的项目自动化构建工具,建立在Apache Ant和Apache Maven概念的基础之上,并引入了基于Groovy的特定领域语言,而避免了使用xml形式管理构建脚本,利于管理维护。
支持编译、测试、打包、依赖管理和发布
核心要点:所有的操作都是通过任务完成的
Task(任务)可以理解为 gradle 的执行单元,gradle 通过执行一个个 Task 来完成整个项目构建工作。
Android APP工程 com.android.application
Android Library工程 com.android.library
Test插件 com.android.test
注意
只有应用项目才可以打包成apk,而一个安卓项目中 除了上面提到的应用项目(必定包含),必然还包含 根项目,再有可能包含Android 库项目
组成 = 根项目 + 应用项目 + n个库项目
在setting.gradle 中通过include 关键字来引入特定的模块
如下,使用implmentation project 依赖项目
dependencies {
...
// 依赖管理,使用implementation pro赖某个project
implementation project(":app:app_module_one")
}
我们来看下主工程下面的build.gradle吧
// 构建项目之前,为项目进行前期准备和初始化相关配置依赖的地方
buildscript {
repositories {
jcenter()
}
dependencies {
// Android Gradle属于第三方插件,所以我们需要先配置依赖classpath,这样gradle才能找到Android插件
// Android Gradle托管在jecenter上
classpath 'com.android.tools.build:gradle:3.6.3'
}
}
初始化 -> 配置 -> 运行
1)初始化 Initialization
Gradle支持同时至少一个项目的构建,在Initialization阶段,Gradle决定哪个项目可以参与构建(build),并为它们分别创建一个Project实例。
setting.gradle 会在Gradle初始化阶段执行,决定哪些项目会参与Gradle的构建过程
2)配置 Configuration
参与构建的所有项目的build script会被执行
3)运行 Execution
Gradle划分完成在配置阶段被创建的即将执行的task,通过gradle命令参数和当前目录确定这些task是否应该得到执行。
DSL(Domain Specific Language)的中文意思是领域特定语言,说白了就是专门关注某一领域的语言,它在于专,而不是全,所以才叫领域特定的,而不是像 Java 这种通用全面的语言 。
Gradle就是一门DSL,它是基于Groovy的, 专门解决自动化构建的DSL。自动化构建太复杂 、太专业 ,我们理解不了,为了帮助人们使用, 专家们就开发了 DSL一-Gradle。我们作 为开发者只要按照 GradleDSL定义的语法,书写相应的 Gradle脚本就可以达到自动化构建的
目的,这也是 DSL 的初衷 。
在build.gradle文件中通常会定义版本名称、版本号、开源项目的版本等,为了便于维护我们最好能够将这些常量可以提取到配置文件中,也是方便我们可以修改和日常的维护。
上面两种方式的弊端是,没有代码补全,要使用变量还得一个一个写或者复制,在编译前并不能确定键入的是否正确。而我们通过在buildSrc构建配置groovy文件确能够到达索引资源的目的。
具体步骤
1、在项目根目录下新建 buildSrc文件夹,然后新建 src/main/groovy文件目录
在此目录下新建自定义文件夹如 config,然后建立所需要groovy文件,如下图所示
注意根目录下文件夹名称一定为 “buildSrc”,注意groovy为代码目录,即应该是蓝色,如果是浅色可如下进行设置。右击目录,选中“Mark Directory as” => “Sources Root”
我们在Android目录下进行查看
注意
创建完毕只有,一定要重新进行编译,如上图所示出现.iml和build等文件或者文件夹
2、在build.gradle进行使用
如下我们就可以使用自己定义的配置文件变量了。包括版本号,依赖的版本等,可以很方便的进行管理而且可以索引到进行跳转。
参考博客
新建buildSrc目录,并新建build.gradle.kts,引入插件,设定仓库
在src/main/java 新建kotlin文件并设置配置值
使用时直接调用即可
这种方式好归好,但是有下面的缺陷。
1、一定要引入kotlin-dsl 插件,增加了依赖占用更多空间
2、出现如下警告
3、模块依赖查看不了,虽然这个不重要,但是有强迫症看起来很不舒服
一个APP只有通过release签名打包之后才能发布、安装、使用。我们可以通过Gradle配置我们的签名认证信息,那么只需要运行打包即可,避免了选择文件录入信息的过程。具体看下怎么实现的
首先放置好我们的jks打包文件,我这里将jks和app的build.gradle文件放在同一级下面
android {
......
// 对签名进行配置
signingConfigs{
// 仅对release进行配置
release{
storeFile file("./helloJni.jks")
storePassword "123456"
keyPassword "123456"
keyAlias "helloJni"
v1SigningEnabled true
v2SigningEnabled false
}
debug{
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// 将release配置引入打包类型
signingConfig signingConfigs.release
}
}
如下图所示,点击右上角的gradle 图标,选择app/Tasks/other文件
然后点击assembleRelease完成打包任务
android{
// 修改文件名
// 遍历产物
android.applicationVariants.all {
variant ->
variant.outputs.all {
//只处理生产版本
if (buildType.name == 'release') {
def buildTime = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08:00"))
// app包名称
outputFileName = "jni_release_v" +
Versions.versionName + "_" + buildTime + ".apk"
////指定release输出到指定文件夹
}
}
}
}
具体安装docker 以及在docker中运行Nexus 可以参考网上文章,如下
Mac中 安装 docker 中搭建 nexus
新建私有仓库
点击左上角的添加按钮,添加一个hosted类型的私有仓库
docker中启动关闭Nexus方法截图
模块上传aar需要在该模块对应的build.gradle中支持maven插件,然后配置仓库地址、
组名、包名、版本号等,如下所示
apply plugin: 'com.android.library'
apply plugin: 'maven'
...
// maven插件包含任务
uploadArchives {
repositories {
mavenDeployer {
snapshotRepository(url: "http://localhost:8081/nexus/content/repositories/snapshots/") {
authentication(userName: "admin", password: "admin123")
}
// 仓库地址
repository(url: "http://localhost:8081/nexus/content/repositories/apple/") {
// 用户名密码
authentication(userName: "admin", password: "admin123")
}
pom.project {
version '1.0.0' //版本名
artifactId 'model-one-core' //包名
groupId 'com.zxl.model-one' //组名
packaging 'aar' //文件类型必为aar
description '提交model-one 1.0.0版本' //更新描述
}
}
}
}
运行任务,点即上传任务
查看编译上传运行结果
查看私有仓库是否有该aar呢
// 根build.gradle 中配置仓库地址为本地仓库地址
allprojects {
repositories {
google()
jcenter()
maven {
url 'http://localhost:8081/nexus/content/repositories/apple'
}
}
}
// 需要引入该库资源的 build.gradle 添加依赖
dependencies {
.....
implementation 'com.zxl.model-one:model-one-core:1.0.0'
}
至此该aar中的资源我们就可以拿过来使用了
在学习Android Gradle之前也是听说过多渠道打包的,之前浅陋的以为啊这可能和第三方sdk有很大关系之类的,觉得是不是特别高深,经过学习一段实现的Gradle才了解到这里面的玄机还是和Gradle相关,那后续得花时间去探究。
android {
......
signingConfigs {
release{
}
// 设置debug包jks
debug {
storeFile file("/Users/apple/.android/debug.keystore")
storePassword "android"
keyPassword "android"
keyAlias "androiddebugkey"
v1SigningEnabled true
v2SigningEnabled false
}
}
// 设置文件输出名
android.applicationVariants.all {
variant ->
variant.outputs.all {
// 依据变种名 设置后缀
def variantName = variant.name
def versionNameSuffix = ""
if (variantName.contains("ali")){
versionNameSuffix = Versions.Ali.versionNameSuffix
}else if (variantName.contains("baidu")){
versionNameSuffix = Versions.Baidu.versionNameSuffix
}
def buildTime = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08:00"))
// app包名称
outputFileName = Versions.appName+"_"+buildType.name+"_v" +
Versions.versionName+versionNameSuffix+"_" + buildTime + ".apk"
}
}
/**
* productFlavors - 渠道集合
* 定义渠道 baidu & ali
*/
// 设定变种的纬度
flavorDimensions "company"
productFlavors{
// 定义百度渠道
baidu{
// 设置渠道名为baidu
// 为渠道设置变种纬度
dimension("company")
}
// 定义阿里渠道
ali{
// 设置渠道为ali
// 为渠道设置变种纬度
dimension("company")
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
zipAlignEnabled true
}
debug{
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// 设置签名配置
signingConfig signingConfigs.debug
zipAlignEnabled true
}
}
}
编译看下Tasks列表,可以查看到我们定义的渠道ali、baidu分别油生成了release版本和debug版本。我们点击debug版本,来配置生成我们的debug文件,再来查看结果
如下图分别生成了,baidu版本apk和ali版本apk
这里我只是在主页面依据渠道进行了文字设置,具体查看结果
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
TextView textView = findViewById(R.id.tvText);
String flavor = BuildConfig.FLAVOR;
if ("ali".equals(flavor)){
textView.setText("阿里巴巴欢迎您");
}else if ("baidu".equals(flavor)){
textView.setText("百度欢迎您");
}else {
textView.setText("获取渠道名失败");
}
}
其他技巧
// 设置manifest占为
manifestPlaceholders = [ application_id :"xxx.xxx.xxxx"]
// 设置BuildConfig,类型可设定
buildConfigField 'String', 'BASE_URL', '"http://xxx.xxx.xxxx'////测试环境下的网络请求基地址
// 设置资源文件,可为bool等类型
resValue "string", "xx", "xx"
** 单词记录学习**
signingConfigs 签名配置
flavor ['fleɪvə] 风格
手动下载特定版本的Gradle
下载完了之后需要将gradle版本解压出来放入如下文件夹
在上面定义渠道的基础上,针对包类型进行了拓展
Github项目地址
学习文档
Gradle中文文档
Gradle诀窍与提示 Google Developer
一步一步教你在JCenter发布开源库