Gradle入门(二)尝试理解gralde编译项目

2023-11-19

前言

前面我们了解了如何通过groovy DSL转换为KTS,我也在尝试的证明可以看到源码和有代码提示对于入门的重要性。2022年11月12日,我发现最新的idea 有gradle的代码提示,点击也可以看到源码。学习Gradle还是建议整一个最新版本的IDEA。
那么我们这次主要就是通过一些简单的gradle 工程去尝试理解gradle工程。

正文

我们可以直接打开gradle 官网,官网直接包含了我们需要学习的所有gradle 基础。
当然Android 中使用gradle 还需要另外一个网站gradle Androidandorid gradle-api 。要完全理解他们是一个大工程,而业务开发中往往是不要先全部学习的,就和我们从事Android一样,第一份工作的时候往往不是什么都会,那时候可能只会写一些业务,找一些第三方的maven等等,同时这也是这个系列的目的,不是全部要会,我们只需要了解基础然后根据自身需要再去扩展学习。

闲话说了这么久,让我们回到正题上,gradle到底为了我们做了什么?

我们回顾一下自身的诉求,我们编辑的任何代码或者文件,我们想要把它编译成可以被执行的文件,比如apk,比如我们写的Java 文件转换为class,然后再执行。当初上大学的时候,是这么学习Java的:

  • 老师先写一个Java 类。
  • 然后通过环境变量中配置的javahome在cmd 中使用 Javac 把java文件转换为class
  • 然后在cmd 中通过全路径把转换成功的class运行起来。

当我看到控制台打印出刚刚老师写的hello word的时候,有震惊,有放弃,这太复杂了,我这脑子毕业了估计还是工地搬砖吧。后面使用了编辑器以后这种放弃的想法才慢慢的减少,毕竟谁不喜欢写完代码点击运行后可以看到结果的那种满足感呢?

而grade 就是一种构建脚本,它将一系列的检查、编译流程和打包流程串联在一起了,我们只需要点一下运行,要不编译运行成功,要不就直接失败。

简单的Java项目

我们先通过idea创建一个使用gralde构建的Java 项目。如果点开project的话,你就会发现,idea会优先创建一个叫build.gradle 的文件,但是创建进度条还没有到底部,当创建完成后,就会多了很多文件。

同时项目配置中也设置了代码的源码位置:
在这里插入图片描述

编译文件的输出位置:

在这里插入图片描述

这也就说明 build.gradle这个文件是整套编译流程的关键所在。

那么我们尝试去了解一下这个简单Java 工程的build.gradle

plugins {
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

这个文件的内容很简单,主要是导入了Java plugin,然后设置了maven 源地址,然后导入了 junit.那么我们就可以尝试删除一些我们不需要的内容。

plugins {
    id 'java'
}

只有上面代码的时候。Java demo依旧可以运行的。
在这里插入图片描述

当我们移除掉Java plugin的时候,hello 文件就会提示无法运行。那么是否可以佐证一个事实,gralde 构建系统的识别是通过plugin去完成的,而plugin则是构建的关键。

当我们点击dependencies的时候,跳转到源码。可以发现。他其实是 org.gradle.api.Project的一个函数。

在这里插入图片描述

public interface Project extends java.lang.Comparable<org.gradle.api.Project>, org.gradle.api.plugins.ExtensionAware, org.gradle.api.plugins.PluginAware {}

点击plugins的时候
在这里插入图片描述

因为project继承了PluginAware,所以plugin也是添加到project中的。这也说明为啥 apply plugin:‘java’ 也是可以的。

但是kts的 gradle则是KotlinBuildScript:ProjectDelegate。ProjectDelegate继承于Project。

回归到Android 工程

我们发现Android新创建的工程中在根目录有一个build.gradle、setting.gradle 、gradle.properties。

既然可以直接看源码,我就直接点进源码去看。

settings.gradle

这个是settings.gradle 对应的类。

org.gradle.api.initialization.Settings
public interface Settings extends org.gradle.api.plugins.PluginAware, org.gradle.api.plugins.ExtensionAware {}

通常而已,我们创建Android 项目的时候,一开始创建的gradle文件就包含TA了。那我再看默认的内容:

rootProject.name = "GradleDemo"
include(":app")

不同的gradle版本中代码可能不一样,最新的Android studio中 settings.gradle有其他的配置。我们结合代码就可以发现,include 其实是一个类似于相对位置的东西。如果我APP目录上面还有一个目录呢?就可以写成

include 'demos:demo1'

Demos是一个目录结构。那么settings.gralde 帮助我们做了什么吗?
在这里插入图片描述

看到这张图了吗,我们上面也有一张这样的图。gradle 就是通过这个文件将我们需要编译的项目添加到他的构建项目中去的,哪怕你的项目没有一丝丝的关联,所以没有必要参与编译的项目就没有必要添加进来。

根目录下的build.gradle

可以肯定的是这个一定是project,因为自己创建空的工程的时候,手动添加settings.gradle的时候写成了setting.gradle,然后发现他竟然是project,怀疑了下人生,后面发现单词打错了。

直接上代码:

buildscript {
    repositories {
        maven {//本地Maven仓库地址
            url uri('/Users/nuoye/AndroidStudioProjects/GradleDemo/repo')
        }
        google()
        mavenCentral()

    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.2"
        
    }
}

allprojects {
    repositories {
        maven {//本地Maven仓库地址
            url uri('/Users/nuoye/AndroidStudioProjects/GradleDemo/repo')
        }
        google()
        mavenCentral()
        jcenter() // Warning: this repository is going to shut down soon

    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

有过自定义ext的同学就知道,我们ext一般要写到buildscript 里面,写到其他地方在导入classpath的时候会报找不到,这个其实是和这个project的运行周期有关,这个运行周期下一次分享,这次我们只是单纯的了解这些闭包的含义。

buildscript

这个相对来说是最先执行的,同时如果你要添加一个classpth,那么他的maven库就得写到这个闭包下的repositories 里面。否则就会报classpath内容拉取不到。

dependencies 主要作用是导入我们gradle运行需要的代码,比如我们Android的 build-tools。因为我们使用的

plugins {
    id 'com.android.application'
}
android{

}

这些都是我们build-tools里面的内容。

allprojects

这个就对应着我们的module的配置了,repositories 中定义着那些我们module中需要导入的maven仓库地址。当然也可以添加其他配置。目前来说,编译时技术被用的越来越普遍,所以通常而言,两个都要写。

clean task

这个调调是一个清除项目编译缓存的一个task任务。

task clean(type: Delete) {
    delete rootProject.buildDir
}

delete 删除的是一个目录,所以也可以指向自己希望指向的目录。

gradle.properties

这个调调熟悉配置的同学就比较清楚。properties 是一种键值存储的配置文件,他的获取也是有生命周期限制的,但是在settings.gradle 和buildscript 中均可获取到。所以如果这也是一种ext的思路。当然了这个值整个项目都可以拿的到,仔细回想以下,ext 写了也可以拿到,只是没有这么简单。

我们可以这么定义一些自己需要的值。

luoyeAdd=true
luoye=luoye
luoyeInt=1

然后使用的时候可以转换成需要的类型,也可以不转换,看诉求。他是键值存储的,所以不能写赋值。

比如 :

a=5
b=a

我们拿到的b就会是字符串a,而不是5.

APP 目录的build.gradle

结合上面的知识点,我们知道,需要导入一个插件,让gradle清楚我们需要用什么去编译我们的代码。

plugins {
    id 'com.android.application'
}

所以这个调调是必需的。然后就是Android 闭包了的内容了。

总结

我们发现Java 默认的工程并没有根目录的下的build.gradle,同时也没有clear。那么我们可以自己写一个吗?

答案是肯定的,但是添加的时候却提示:

Cannot add task ‘clean’ as a task with that name already exists.

说clean已经存在了,可以换一个名字不是吗?

task cl(type: Delete) {
    delete project.buildDir
}

反正都是删除文件,我们想删除哪里就删除哪里,甚至你可以指向自己的代码目录【一键坐牢】。

还有一个问题,当我们导入的插件只想在某一个module中使用,可以吗?这个好像不行,无论根目录下的build.gradle 还是module的build.gradle 都是project,但是buildscript 是导入gradle执行需要的代码,你导入的plugin 必需得存在于可以运行的gradle中,好像不支持动态加载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Gradle入门(二)尝试理解gralde编译项目 的相关文章

  • Sonarqube如何正确配置gradle子项目?

    我的 gradle 项目结构如下所示 geode core geode lucene extensions geode modules extensions geode modules session For extensions因此 子项
  • 为 customere xml 按钮着色时遇到问题

    我在为自定义按钮着色时遇到问题 由于某种原因 似乎无论我想应用什么颜色更改 文本或背景 按钮都保持不变 我注意到button xml具有所需的颜色和正确的形状 尽管没有出现按钮background color活动的财产 活动中的按钮
  • 如果我在 XML 布局中声明一个片段,如何将它传递为 Bundle?

    我有一个活动已替换为片段 该活动采用了一个 Intent 其中包含一些有关该活动应该显示哪些数据的额外信息 现在 我的 Activity 只是执行相同工作的 Fragment 的包装器 如果我使用标记在 XML 中声明该片段 如何将该捆绑包
  • Android TextToSpeech 行为不规则

    更新 经过一番挖掘 我设法在 Logcat 中找到了一些信息 见底部 编辑2 我现在从头开始创建了一个新活动来减少这个问题 它仍然无法正常工作 这是代码 public class MainActivity extends AppCompat
  • 空指针异常 - findViewById()

    谁能帮我找出这个程序可能存在的问题 在里面onCreate 方法findViewById 为所有 id 返回 null 这会导致稍后出现空指针异常 我不明白为什么findViewById 找不到视图 有什么建议么 这是主要代码 public
  • 如何生成带logo的二维码?

    我正在为 Android 设备开发应用程序 我想生成带有徽标的二维码 With ZXing I know how to generate simple QR codes like this one But I want to generat
  • 将实时 Android 网络摄像头视频上传到 RTP/RTSP 服务器

    我已经做了适当的研究 但仍然缺乏关于我想要实现的目标的信息 因此 我想编写一个应用程序 用户可以在其中录制视频并立即 实时 将视频上传到 RTP RTSP 服务器 服务器端不会有问题 我不清楚的是如何在手机端实现这一点 到目前为止 我的研究
  • 如何设置评分栏的星星颜色?

    如何设置评分栏的星星颜色 我想要黄色星星 最简单的方法 android progressTint color color 光滑有光泽
  • 支持多屏幕[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 支持多个屏幕和不同的屏幕密度必须注意
  • 模拟器的窗口比手机屏幕太大

    我做了一个小例子来测试我的Android环境 当我在AVD上启动执行时 它看起来太大了 就好像它是平板电脑屏幕一样 如何调整大小使其看起来像手机屏幕 Android Studio 2 2更新后就没有了Emulator Tab in Edit
  • Android 自定义对话框中的图标

    有没有一种方法可以在不使用 AlertDialog 方法的情况下在自定义对话框上设置图标 对话框有标题 但缺少漂亮的分隔线和设置图标的功能 但肯定有一种方法可以在不使用 AlertDialog 的情况下获得两者 您可以使用以下代码添加图标
  • 如何将数据从 SQLITE 数据库获取到 Android 中的数组?

    很确定这是一个简单的问题 但我对所有将从游标返回的数据适应不同视图的示例感到困惑 我只想运行原始查询并将返回的每一项数据放入浮点数组中 以便我稍后可以将它们添加起来 我需要为此使用什么 Thanks 当您查询数据库时 您仍然会有一个游标 但
  • 带 LiveData 的嵌套观察者(观察观察者)

    我有一个案例 我有 BottomNavigationView 其中片段被显示 隐藏而不是添加 替换 因此它们不会每次都经历生命周期 片段1正在观察一个数据库表 片段2正在观察一个不同的 我的目标是调用 onChanged片段2当 on 改变
  • Android NDK __android_log_print函数和LogCat

    我有一个类似的功能 android log print ANDROID LOG INFO HelloNDK 在我的 C 代码上 我在 LogCat 上找不到该输出 我需要设置什么样的过滤器 按日志标签 按日志消息 按应用程序名称 按日志级别
  • Android 是否可以获取用户和设备所在国家/地区的货币代码?

    是否可以获取用户和设备所在国家 地区的货币代码 我想将用户当前国家 地区的国家 地区代码设置为默认国家 地区 我们在 Android 中有解决方案吗 由于这段代码可能对您有帮助 public class CurrencyTest publi
  • 在 Android 谷歌地图中绘制 4K 折线

    我现在正在开发一个适用于 Android 设备的应用程序 主要功能是在地图上绘制折线以显示城市中每条街道的交通情况 不幸的是 当我绘制大约 3K 折线时 数量会根据屏幕尺寸和缩放级别而减少 我的地图变得非常慢 我没有提及绘制所有线条的时间
  • 在 Android 中的计时器内运行异步任务

    我正在开发一个基本的聊天类型应用程序 目前我正在运行代码 如下所示 class GetMsgs extends AsyncTask
  • Android 是否可以同时使用前后摄像头[重复]

    这个问题在这里已经有答案了 我想同时使用设备的前置和后置摄像头 在我的应用程序中 屏幕的前半部分将显示后置摄像头的预览 屏幕的下半部分将显示前置摄像头的预览 我尝试过设置两个不同的相机预览 但是当我打开应用程序时 屏幕的前半部分 显示后置相
  • 如何在 Android 上从后台线程显示 Toast?

    我怎样才能显示Toast http developer android com guide topics ui notifiers toasts html来自线程的消息 您可以通过调用Activity s runOnUiThread您线程中
  • Pinterest 喜欢自定义 GridView

    我是 Android 新手 我正在寻找网格视图的逻辑 例如为 iPhone 构建的 pinterest homescreen 应用程序 一个大号 图像来自服务器 我需要以以下形式显示并具有分页效果 即在滚动上加载图像 如果可以的话请回复 我

随机推荐

  • 计算机图形学 3D渲染 笔记(一)

    1 坐标系 大多数计算机屏幕采用的坐标系是以左上角为原点 水平 右 为x轴 纵向 下 为y轴 3D图形学习中通常使用另一种坐标系 即 正中心为原点 水平 右 为x轴 纵向 上 为y轴 当前者坐标系转化到后者 需要进行简单的转化 Sx Sy为
  • IDEA2021.2安装与配置(持续更新)

    IDEA2021 2安装与配置 持续更新 一 下载 二 安装 三 配置 3 1 配置全局生效 3 2 首次启动 3 3 激活 3 4 字体 字体大小 3 5 配色方案 3 6 注解生效 3 7 自动导包移包 3 8 自动补全快捷键 3 9
  • vue-nginx刷新404问题

    文章目录 1 背景介绍 2 问题描述 2 1 问题一 2 2 问题二 3 原因分析 3 1 问题一 3 2 问题二 4 排查问题一原因 5 反思 6 nginx root与alias的使用 7 更优雅地解决vue网页浏览器刷新404 7 1
  • Mongodb——使用Mongodb对字段中字符串内容进行截取,并进行分组统计

    最近忙的厉害 除了发一发之前写的存货只能写一些简单的东西了 这里就简单分享下最近遇见针对数据进行指标统计遇见的问题 针对字段中某部分内容的指标统计 在使用mongodb进行指标统计的时候可能遇见下面的数据结构 1 id ObjectId 5
  • 短信备份到另一个手机android,旧手机的短信怎么转移到新手机上?三种方法总有一种适合你...

    手机短信一直以来都是我们和其他对象传输信息的工具 更是存储了大量重要的信息 如果我们更换手机需要保留下来这些短信该怎么办呢 有没有什么方法可以将这些短信转移到新手机中去 或者导出到电脑上进行保管呢 这里有三种方法 第一种方法用内存卡 可以打
  • C++仿函数

    1 仿函数的定义 仿函数简单说就是在类中定义的特殊函数 没有函数名 或者说函数名统一为 operation 或者可以认为是重载运算符 格式为 返回类型 operator 参数列表 定义了仿函数的对象 可以直接通过下面格式调用仿函数 对象名
  • 异步加载vue组件

    什么时候使用 组件较大 或者不是必用的 通常组件在script标签对中导入 而异步组件在component中使用 例如 components ForData gt import view Fordata
  • J2EE集合框架

    1 UML 二 集合的基本特点 list集合的特点 增删改查 有序 可重复 三 List集合的三种遍历方式 for foreath iterator 四 ArrayList LinkedList 的比较与分析 比较 1 ArrayList
  • 基于Matlab的灰狼算法优化LSTM风电功率预测

    基于Matlab的灰狼算法优化LSTM风电功率预测 随着可再生能源的快速发展 风能作为一种重要的清洁能源形式变得越来越受关注 风电功率预测在风电场的运营和调度中起着关键作用 然而 由于风速的不稳定性和不确定性 精确地预测风电功率仍然具有一定
  • SpringCloud Gateway:status: 503 error: Service Unavailable

    使用SpringCloud Gateway路由请求时 出现如下错误 yml配置如下 可能的一种原因是 yml配置了gateway discovery locator enabled true 此时gateway会使用负载均衡模式路由请求 但
  • Lim接口测试平台-接口测试功能详解

    一 接口测试 项目地址 Gitee Github 接口测试模块是整个Lim平台的核心 左侧是接口的模块树 右侧顶部是用例操作功能区 列表展示接口用例信息 文章目录 一 接口测试 二 维护接口用例 各步骤类型详解 1 执行步骤 1 接口步骤
  • Unity --- 触摸方法,以及灯光与烘培的使用

    触摸方法 1 首先触摸分为两大类 多点触摸和单点触摸 这两种方式的触摸通过下面这个触摸数来进行判断 当其等于1的时候 为单点触摸 当其大于1的时候为多点触摸 2 当我们在调用触摸方法的时候我们首先需要打开对应的多点 单点触摸 上面这个是开启
  • QObject的d_ptr成员——箭头符号的重载

    QObject中的d ptr是这样定义的 QScopedPointer
  • vscode cmake 编译32位程序

    vscode cmake 编译32位程序 为什么要用cmake vscode中的C C 插件直接支持的只是最简单的单文件编译 运行和调试 要管理大的项目 或者生成库 C C 插件不能直接支持 需要开发者利用vscode的task功能 结合脚
  • 【由浅入深】爬虫技术,值得收藏,来了解一下~

    爬虫技术 来了解一下 一 为什么需要爬虫技术 现在的互联网来说 包含着各种海量的信息 无孔不入 包罗万象 出于数据分析或产品需求 我们需要从某些网站 提取出我们感兴趣 有价值的内容 我们需要一种能自动获取网页内容并可以按照指定规则提取相应内
  • 关于两数交换的两种方法

    目录 前言 一 引入变量 这个方法也是最常用的方法 二 通过使用数学的方法相加或者相减从而得到两数运算 这种方法不常见 总结 前言 从键盘输入两个整数 并交换两位数字 这里小编用两种方法告诉大家 注意小编这里用的是VS2019 所以在代码的
  • STM32 --通用定时器输入捕获功能

    问题 开始的时候没有搞清楚 定时器时基 于 定时器溢出中断的概念 导致在计算频率的时候一直有问题 开始并没有怀疑是配置有问题 因为之前接触过定时器输入捕获功能 靠着自己的记忆配置了一下 认为 捕获功能 的定时是通过定时器设置的定时溢出频率来
  • 栈实现队列(继续细起来啊)

    生命不是要等待风暴过去 而是要学会在风暴中跳舞 卡莉尔 吉布朗目录 一 栈实现队列 二 使用两个栈实现队列的功能 1 在队列的结构体中创建两个栈 2 创建一个队列的结构体指针 3 myQueuePush入队列操作 4 myQueuePeek
  • SpringBoot项目实战(一)

    SpringBoot实战之系统架构 1 系统介绍 该实战项目 是一个B2C模式的职业技能在线教育系统 分为前台用户系统和后台运营平台 前台用户系统包括课程 问答 文章三大部分 后台运营平台包括会员管理 讲师管理 课程管理 文章资讯 统计分析
  • Gradle入门(二)尝试理解gralde编译项目

    前言 前面我们了解了如何通过groovy DSL转换为KTS 我也在尝试的证明可以看到源码和有代码提示对于入门的重要性 2022年11月12日 我发现最新的idea 有gradle的代码提示 点击也可以看到源码 学习Gradle还是建议整一