美文网首页
日更挑战-Gradle简单认识

日更挑战-Gradle简单认识

作者: 愿你我皆是黑马 | 来源:发表于2021-06-08 20:46 被阅读0次

    越不懂的越爱装
    大家都同等:IT世界没有难不难,只有是否了解过

    挑战目录

    什么是gradle

    是基于Groovy(运行在JVM上的一种语言)的项目构建工具(你说我们写一个jar包来进行项目构建是不是一样的)

    • 自动配置依赖的第三方库和jar包
    • java源码,res等资源编译打包成apk
    • 支持写脚本扩展 编译和打包规则 等
    • ...

    gradle脚本执行的过程

    • 初始化:创建项目实例。如果一个项目有多个build.gradle那么就会为每个模块创建项目实例
    • 配置:执行构建脚本,创建并配置任务
    • 执行:执行被指定的任务。

    脚本构成

    • Project:表示单个脚本文件。xxx.gradle就表示Project为xxx

    • Task:定义在xxx.gradle中的可执行的任务方法, 代表一个构建工作

      task myTask
      task myTask { configure closure }  // closure是一个闭包
      task myType << { task action }    // <<符号是doLast的缩写  
      task myTask(type: SomeType)   // SomeType可以指定任务类型,Gradle本身提供有Copy、Delete、Sync等
      task myTask(type: SomeType) { configure closure }
      
    • Action: doFirst和doLast

      • doFirst:可以在配置阶段后,运行阶段时运行前执行某些操作 (比如在下面的type:Delete的默认执行执行前)

        部分同下(改名字即可)
        
      • doLast:和上面同理,只是在执行后执行某些操作

        task myType << { task action }
        task myType  { doLast{task action} }
        task myType.doLast  { task action }
          task myType(xxx).doLast  { task action }
        
      • doFirst和doLast举例

        task order(dependsOn:'a'){
           println("test doNormal") //在配置阶段这个就会执行,不管这个任务有没有被运行
        
           doLast { 
               println("test doLast")
           }
        
           doFirst {
               println("test doFirst")
           }
        }
        
        task a{
           println("a doNormal")  //在配置阶段这个就会执行,不管这个任务有没有被运行
        
           doLast {
               println("a doLast")
           }
        
           doFirst {
               println("a doFirst")
             }
        }
        

        上述的输出为:

        18:53:45: Executing task 'order'...
           
        Executing tasks: [order] in project E:\project\and\app_temp_new
           
        > Configure project :app
        WARNING: The option setting 'android.enableBuildCache=false' is experimental and unsupported.
        The current default is 'true'
           
        > Configure project :.................
           
        > Configure project :base:common
        WARNING: The option setting 'android.enableBuildCache=false' is experimental and unsupported.
        The current default is 'true'
           
        test doNormal
        a doNormal
           
        > Configure project :.................
           
        > Task :base:common:a
        a doFirst
        a doLast
           
        > Task :base:common:order
        test doFirst
        test doLast
           
        BUILD SUCCESSFUL in 12s
        2 actionable tasks: 2 executed
        18:53:57: Task execution finished 'order'.
        

    build.gradle在gradle中充当的角色

    Gradle默认执行当前目录下的build.gradle文件,代表名字为build的Project


    gradle基本语法

    • 修饰符:默认是public

    • 变量定义:动态推断型(def也可以用来声明方法) def xxx="??" ,直接指定型String xxx="??"

      1. 全局变量(所以.gradle都能获取)
        • gradle.properties配置文件

          //gradle.properties文件
          isBuidMode=false
          

          注意:gradle.properties配置文件只能赋值字符串,所以使用的时候需要转型。
          比如上面的:
          if (isBuidMode.toBoolean()) {
          ...
          } else {
          ...
          }

        • ext

        • 命令行参数

      2. 局部变量(只有当前.gradle能获取)
    • 可省略的情况:

      1. 语句后面的分号
      2. def和变量类型的其中之一(不能全部都省略)
      3. def和方法的返回值类型的其中之一(不能全部都省略)
      4. 调用方法时的圆括号
      5. 方法中的参数类型
      6. 方法的最后一个表达式可以作为返回值,不需要return语句
    • 条件:同java

    • switch :不固定case的类型switch (x){case 多种类型:xxx}

    • 断言:assert设置断言,如果为false则会异常退出

    • 比较:Groovy的is()方法相当于java的==,==相当于java的equals()。所以比较类时要用a.is(b)

    • 循环

    • 闭包

    • 任务依赖:在执行taskA之前先执行taskB

      1. 被依赖项定义在依赖项之前

        task b << {
             println 'i am b'
            }
        task a(dependsOn: b) << {
         println 'i am a'
        }
        
      2. 被依赖项定义在依赖项之后(需要使用引号引起来)

        task a(dependsOn: 'b') << {
         println 'i am a'
        }
        task b << {
         println 'i am b'
           }
        
    • ................


    Type

    从安卓项目中可以看到类似下面的任务

    task clean(type: Delete) {
        //在配置阶段这个就会执行,不管这个任务有没有被运行
        delete rootProject.buildDir //省略括号的方法调用
    }
    

    跟踪可以看到如下:

    /**
    * @return The build directory. Never returns null.
    */
    File getBuildDir(); //build文件夹
    

    跟踪delete可以看到如下:

    //将build文件夹放到Set<Object> delete中
    public Delete delete(Object... targets) { //targets传进来长度为1的 build文件夹目录
        for (Object target : targets) {
           this.delete.add(target);  // private Set<Object> delete = new LinkedHashSet<Object>();
        }
        return this;
    }
    

    上面执行完成后就在配置阶段将build目录添加到delete里面了。

    在public class Delete extends ConventionTask implements DeleteSpec里面可以找到如下方法,真正删除build文件夹

    @TaskAction //标识在执行这个任务的时候执行该方法
    protected void clean() {
        Deleter deleter = new Deleter(getFileResolver(), getFileSystem());
        final boolean innerFollowSymLinks = followSymlinks;
        final Object[] paths = delete.toArray();
        setDidWork(deleter.delete(new Action<DeleteSpec>(){
            @Override
            public void execute(DeleteSpec deleteSpec) {
                deleteSpec.delete(paths).setFollowSymlinks(innerFollowSymLinks);
            }
        }).getDidWork());
    }
    

    综上我们可以看出来type: Delete就相当于继承java代码写的Delete任务,继承后我们可以使用相应的方法属性
    其他的预定义type :
    Copy 、Sync、Zip
    上面的可以参照文章预定义type


    应用插件

    自定义gralde插件(暂时没写以后在写)


    安卓中build.gradle的特定元素

     buildscript*:

    1. 指定项目依赖的仓库地址(repositories)
    2. 配置使用的插件地址(dependencies)
    buildscript {
        repositories { //下面是配置仓库中心的多种形式
            maven {
                credentials {
                    username NEXUS_USERNAMEy
                    password NEXUS_PASSWORDy
                }
                url MAVEN_REPO_RELEASE_URLy
            }
            flatDir{
                dirs '../../base/libs'
            }
            maven { url 'https://dl.bintray.com/umsdk/release' }
            google()
            jcenter()
        }
        dependencies { //配置项目使用插件地址,里面存在很多预定于插件和预定义规则
            classpath 'com.android.tools.build:gradle:3.2.1'
            classpath "com.alibaba:arouter-register:1.0.2"
            //gradle 3.2.1 -> 对应doraemonkit-plugin:3.1.5
            classpath 'com.didichuxing.doraemonkit:doraemonkit-plugin:3.1.5'
            classpath 'com.bugtags.library:bugtags-gradle:2.1.5'
        }
    }
    

    allprojects、buildscript、buildscript.repositories、buildscript.repositories.maven等预定于字段

    gralde源码简析(暂时没写以后在写)


    什么是Gradle Wrapper

    实质上是一个脚本,自动使用申明版本的gradle 执行构建任务
    新建项目时,将gradle-wrapper.jar&gradle-wrapper.properties 拷贝到项目的gradle/wrapper目录

    • 配置文件 gradle-wrapper.properties
      //指定Wrapper使用的gradle版本。如果本地没有它会去下载在distributionBase+distributionPath路径。
      distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
      //GRADLE_USER_HOME代表的路径是~/.gradle/文件夹。
      distributionBase=GRADLE_USER_HOME 
      //下载放置的路径的一部分
      distributionPath=wrapper/dists
      zipStoreBase=GRADLE_USER_HOME
      zipStorePath=wrapper/dists
      
    • gradle-wrapper.jar jar包
      用来在对应gradle版本不存在时,下载gradle 的jar工具包

    常用的Gradle命令

    • 查看依赖树:gradle xxx:dependencies (xxx为settings.gradle中include的模块名)
    • 查看版本号: gradle -v
    • 显示所有的Project: gradle projects
    • 显示gradle的gui:
    • 显示所有的task: gradle tasks
    • 编译执行某个task: gradle Task名
    • 静默编译执行某个task: gradle -q Task名
    • 编译执行某个Project中的某个task(build.gradle表示build Project其他.gradle文件同理): gradle -b Project名 Task名
    • 查找所有的gradle命令: gradle --help

    相关文章

      网友评论

          本文标题:日更挑战-Gradle简单认识

          本文链接:https://www.haomeiwen.com/subject/fmwjeltx.html