51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 727|回复: 0
打印 上一主题 下一主题

[资料] gradle的自我介绍

[复制链接]
  • TA的每日心情
    无聊
    2024-10-29 09:20
  • 签到天数: 76 天

    连续签到: 1 天

    [LV.6]测试旅长

    跳转到指定楼层
    1#
    发表于 2022-8-9 13:53:25 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
    1、gradle基本原理
    Gradle是一种以Groovy语言为基础的自动化构建工具
    自动化构建本质上也是一种程序,我们开始编译时就启动这个程序,然后读取我们在 gradle 文件中配置的参数来实例化各个类,然后按照顺序依次执行对应的任务即可完成整个构建任务。
    所以 build.gradle 文件,或者其他后缀为 gradle 的文件其实就是个配置文件,就好像 xml 一样,我们在 gradle 文件中修改各种配置参数,Gradle 通过这些参数来实例化 Project 等等就像构造器一样,只要理解了这点学习 Gradle 就会变得很容易。


    2、gradle的脚本
    当我们新建一个项目后,Gradle 默认会生成一些编译脚本文件,主要有:setting.gradle、build.gradle 以及子项目中的 build.gradle 等等,还会在当前目录下生成一个 gradle 文件夹,下面分别介绍一些这些文件的作用:
    setting.gradle 用来告诉 gradle 这个项目包含了那些子项目。
    include ':app',
            ':umeng-share-sdk',
            ':core-base-libr',
            ':emchatsdk',
            ':floatwindow'
    include ':libsuperplayer'
    build.gradle 是默认的构建脚本,当我们在执行 gradle 命令时,会首先到当前目录下寻找该文件,然后通过该文件的配置实例化一个 Project 对象
    自动生成的 gradle 文件夹是 Gradle 包装器,其中包含一个 jar 文件和一个 配置文件,使用这个包装器可以让 Gradle 运行在一个特定的版本上,目的是创造一个独立于系统、系统配置和 Gradle 版本的可靠和可重复构建。
    Gradle 中有两个重要的概念,分别是 Project 和 Task,Project 表示一个正在构建的项目,而 Task 表示某一个具体的任务。


    3、Project
    Project 表示正在构建的项目,每个 Project 都对应一个我们在 setting.gradle 中配置的 Project,除此之外还有一个 Root Project。
    Project 用来管理、描述当前正在构建的项目,我们可以通过其中提供的 api 进行一些操作来达到自己的目的。


    一个 Project 可以创建新的 Task,添加依赖关系和配置,并应用插件和其他的构建脚本。


    另外,Project 是通过我们常见的 build.gradle 文件实例化出来的,我们在 build.gradle 文件中进行的各种配置最终都会应用到 Project 中去。

    4、Task
    Task 定义了一个当前任务执行时的最小单元,一个 Project 中一般会存在很多个 Task,通过执行这些 Task 来完成整个项目的构建。也就是说,项目构建的实际工作是由一个个的 Task 来完成的。

    Gradle 中的依赖
    Gradle 中的依赖可以分为脚本文件依赖、插件依赖以及包依赖。
    脚本文件依赖
    随着项目结构的复杂,一个 build.gradle 已经无法满足我们的需求了,尤其是对依赖库版本的配置,如果多个 project 都需要用到某个依赖库,稍有不慎版本就会错乱,从而引发一些问题。
    此时我们期望可以把所有用到的依赖库版本都配置在同一个文件中,build.gradle 使用这个文件中的版本来依赖相应的版本,Gradle 提供了 apply 方法来依赖其他文件。
    apply from: 'config.gradle'
    我们可以在 build.gradle 文件中添加上述代码来依赖 config.gradle 文件,这样就可以把这个文件中的设置应用到对应的 Project 中去,包括其中的 Task。插件依赖


    插件依赖是指依赖编译插件,最常见的是我们新建一个 Android 项目时,对应 module 的 build.gradle 文件第一行自动添加的安卓插件:



    apply plugin: 'com.android.application'


    与上一节的脚本文件依赖一样,都使用 apply 函数添加依赖,其中 plugin 后面跟的是插件的 ID 或者全限定类名,我们后面会介绍如何设置插件名。

    通过上面的一行代码就可以把这个插件应用到当前的编译脚本中去,但对于自定义插件来说,我们还需要做一些其他的工作。

    对于 Gradle 来说,依赖一个插件需要分如下三步:

    1. 设置这个插件对应的仓库地址

    我们首先应该设置一些仓库地址,告诉 Gradle 应该去哪里下载我们配置的这些插件和依赖包。

    设置仓库地址通过 repositories 函数来实现,当我们创建好一个项目后,在根 build.gradle 文件中一般会自动添加如下两个依赖仓库:
    1. allprojects {
    2.     repositories {
    3.         google()
    4.         jcenter()
    5.     }
    6. }
    复制代码

    上面代码就是在本项目中添加了两个仓库:google 以及 jcenter.

    因为 google 和 jcenter 两个仓库比较常用,所以默认提供了这两个方法,如果我们希望设置自己的仓库也是可以的,以 Github 的仓库为例:

    1. allprojects {
    2.     repositories {
    3.         maven { url "https://jitpack.io" }
    4.     }
    5. }
    复制代码

    实际上,除了通过上述的方式配置仓库地址外,还有另一种方式设置仓库,就是在项目中创建 buildSrc 子项目,这个后面会详细介绍。

    2. 设置这个插件所在包的全限定名

    仓库地址配置好后,我们就可以使用该仓库中的插件了,插件依赖使用 classpath 函数来完成:

    1. buildscript {
    2.     dependencies {
    3.         classpath 'com.android.tools.build:gradle:3.5.3'
    4.     }
    5. }
    复制代码

    这一步相当于去上面配置的仓库中下载这个插件所在的依赖包,这个依赖包中可能包含很多个插件,有了依赖包我们才是使用其中的插件。

    3. 通过插件名将该插件设置到对应的编译脚本中

    到了这里,准备工作就已经全部搞定了,该有的东西都有了,现在如果我们希望在当前的编译脚本中使用某个插件,直接使用上面介绍过的 apply 函数既可:

    apply plugin: 'com.android.application'

    另外,这里面说的插件是指编译脚本插件,是在编译时使用的工具,用来控制编译的,跟实际的项目开发时的代码没有关系,与我们常说的在项目开发中使用的依赖包不同。

    包依赖

    包依赖其实是个笼统的概念,包括上面说的插件依赖其实也属于包依赖,本章所说的包依赖单纯是指在实际项目开发中使用的一些第三方的依赖库,例如 OkHttp、Gson 等等,这其实不属于编译脚本的范畴,但毕竟也是 Gradle 依赖的一部分,所以也大概说一下。

    包依赖与脚本依赖本质上都一样,都分为三步:

    1. 设置包所在的仓库

    设置仓库地址跟上面说的一样,都是通过 repositories 函数来实现。

    2. 下载需要使用的依赖包

    声明依赖包需要在对应项目的 build.gradle 的 dependencies 函数中完成。

    1. dependencies {
    2.     // 声明一个本地模块的依赖
    3.     implementation project(":mylibrary")
    4.     // 声明一个本地二进制包的依赖
    5.     implementation fileTree(dir: 'libs', include: ['*.jar'])
    6.     // 声明一个远程二进制包的依赖
    7.     implementation 'com.example.android:app-magic:12.3'
    8. }
    复制代码

    此外,还有很多种不同的声明的依赖方式,每种方式都具有不同的依赖特质,具体可以看下表:

    1. 表出处:https://developer.android.com/studio/build/dependencies?hl=zh-cn
    复制代码

    3. 使用该依赖包

    通过上面两个步骤之后,我们就可以在 Java 代码或者其他语言的代码中使用依赖包中的代码了。

    上面就是依赖包的使用方式。我们可以使用 dependencies Task 查看指定项目的依赖树:

    1. //查看 app 模块的依赖树
    2. gradlew app:dependencies
    复制代码

    上面的命令将会输出一个树形的依赖关系表。

    Gradle 插件

    上面叙述的 Task 都是完成一些简单的动能,但对于一些更加复杂,或者可以被更广泛使用的功能来说,直接在 gradle 文件中定义 Task 已经很难满足我们的需求了,因此,Gradle 提供了插件的概念来解决这个问题。

    编写 Gradle 插件有两种方式,一种是创建一个名为 buildSrc 的子项目,在这个子项目中编写插件代码,buildSrc 是 Gradle 插件的默认目录,会把这个目录下的插件自动添加到当前项目中去,我们可以在别的子项目中直接使用。

    另一种方式是把插件写在其他目录,然后上传到 maven 仓库,其他项目通过 maven 的方式依赖这个插件。

    为了方便起见,这里以 buildSrc 为例,由于 buildSrc 不是标准的 Android 项目,所以我们先手动 New module 一个子模块出来,然后选择 Java Library。

    创建好后,打开这个模块的 build.gradle 文件,把最上面一行的 java-library 插件改成 groovy 插件,以及添加需要的依赖包:

    1. //apply plugin: 'java-library'
    2. apply plugin: 'groovy'

    3. dependencies {
    4.     implementation gradleApi()
    5.     implementation localGroovy()
    6. }
    复制代码

    然后,因为插件使用的是 groovy 编写,所以还需要把 buildSrc 下面的 java 目录删掉改成  groovy 目录,完成后如下图所示:

    这样一个 groovy 项目就创建好了。

    我们现在开始编写插件,编写插件的方式很简单,只需要在 groovy 目录下创建一个实现了 Plugin 接口的 groovy 类既可:

    1. class PrintVersionPlugin implements Plugin<Project> {
    2.     @Override
    3.     void apply(Project target) {
    4.         target.tasks.create("PrintVersionTask"){
    5.             doLast{ println("PrintVersionPlugin version:1.0") }
    6.         }
    7.     }
    8. }
    复制代码

    Plugin 接口只包含一个 apply  方法,我们拿到该方法的 project 参数后,就可以做一些自己的操作了,project 提供了丰富的 api,我们可以完成很多事情,例如创建一个 Task。

    插件写好后,我们还需要为该插件创建一个 id,使用这个插件时直接使用这个 id 既可。创建 ID 映射很简单,在 groovy 同级目录下创建一个 resources\META-INF\gradle-plugins 文件夹,然后在这个文件下创建 ID 映射文件,文件名就是这个插件的 id,后缀为 properties,然后把插件类的全限定名按照如下格式写进去既可。

    例如我们把上面插件的 ID 命名为 printVersion,那么我们创建一个 printVersion.properties 文件,然后编写如下代码:

    1. implementation-class=com.zhangke.gradle.PrintVersionPlugin
    复制代码

    此时的 buildSrc 项目目录结构如下:

    这个时候我们就可以在别的子项目中使用这个插件了:

    apply plugin: 'printVersion'

    如果我们希望在一个单独的目录下编写插件,然后上传到 maven 仓库也是可以的,上传 maven 仓库可以用 maven 插件很容易实现,这里就不具体叙述了。



    Gradle的使用教程 点击进入>>>







    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-23 08:40 , Processed in 0.067809 second(s), 25 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表