Gradle自动化构建(九) Project

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huanghuangjin/article/details/82318625
Project 就像android中的activity

gradlew projects // 打印项目中所有projects,对于Gradle来谁,module是一个project,项目根目录也是一个project。 即拥有 build.gradle 文件的目录都算一个project
    Root project 'hjMedia' // 根project主要是用来管理其他子project的
    +--- Project ':OpenCV342'
    \--- Project ':app'

Project API :
这里写图片描述

hjMedia

this.hjgetProjects() // 随便执行一个gradlew命令都会调用project的build.gradle , build.gradle 都是在gradle生命周期的配置阶段调用的
def hjgetProjects() { // 编写函数输出所有的Projects, 与 gradlew projects 命令同效
    // getAllprojects 表示获取所有Projects, eachWithIndex 表示遍历
    // getSubprojects 函数表示获取当前project下的所有子project
    this.getAllprojects().eachWithIndex { Project project, int index ->
        if (index==0) { // 下标为0的Porject为根Project,其他为子Project
            println "root project : ${project.name}"
        } else {
            println "+--- project : ${project.name}"
        }
    }
}
println "getRootProject : ${this.getRootProject().name}" // getRootProject() 获取根project , 可使用 rootProject 代替

// project api
// 'app' 表示从该project下去找名叫 app 的project , pro 表示找到的 app project
project('app') { Project pro ->  // project('app') 函数表示在此project配置其子project app
    apply plugin: 'com.android.application' // 为app指定 plugin
    dependencies {} // 还可以为app指定 dependencies 、 android 等模块,及其他所有app有的
    android {} // 如果在这里指定 app 的配置,那么在 app 的build.gradle 中就可以什么都不写了
}

allprojects { // allprojects 表示为此project及所有子project做配置,闭包的输入参数也是一个 Project 类型变量
    group 'hj.hj' // 指定 group , 可以设为公司域名
    version 'vv1.0' // 指定 version
}
println project('app').group // hj.hj

subprojects { // subprojects 表示为所有子project做配置,不包括此project ,闭包的输入参数也是一个 Project 类型变量
    Project pro ->
    if (pro.plugins.hasPlugin('com.android.library')) { // 获取project中所有插件,看是否包含 com.android.library 插件
//        apply from: 'xxx.gradle' // apply from: 表示导入一个 .gradle 配置文件到此build.gradle , 就像java的import 一样
    }
}
// Project的路径分割符为 : ,参看Project源码的成员属性

// 属性拓展
subprojects {
    ext { // 为所有子project对象拓展成员属性, 这种方式属性是在所有子project对象中重复定义的
        abdA = 'haha'
    }
}
ext { // 为根project拓展属性,在子project中可以通过获取父project的对象来调用拓展的属性,减少了subprojects方式定义产生的冗余
    adcB = [map: 44] // map
}
// 除了在 .gradle 文件中为project拓展属性外,还可以在根目录下的 gradle.properties 中拓展属性(只能使用 key=value 的形式来定义) , 定义的属性可在所有 .gradle文件中使用
// 拓展的属性,不要与Gradle自带的属性重名,否则编译的时候可能不报错,但是运行时报错

// file 相关,gradle提供的这些file api 大多只适用于工程目录下的文件操作,如果要跨工程的文件操作还是要使用 groovy 的中方法
println "root dir : "+getRootDir().absolutePath // root dir : E:\MyProject\studio\hjMedia , 获取根目录
println "build dir : "+getBuildDir().absolutePath // build dir : E:\MyProject\studio\hjMedia\build , 获取当前project的build路径
println "project dir : "+getProjectDir().absolutePath // project dir : E:\MyProject\studio\hjMedia , 获取当前project的路径
try {
    // file() 会从当前project目录下找指定的文件(可以传相对路径),找不到会报错 。 如果要找多个文件使用 files() 函数,用法与 file() 一样
    println file('common.gradle').text[0..<5] // ext {
} catch (GradleException e) { // gradle的try catch 最好用 GradleException
    println 'file(\'common.gradle\').text[0..9] error.'
}
copy { // copy 函数,实现文件的拷贝, 此函数在 .gradle 文件的 Sync Now 的时候就会执行
    from file('app/build/outputs/apk/') // from 表示拷贝哪个文件,此种拷贝方式还可以拷贝整个文件夹
    into rootProject.buildDir.path+"/apk/" // into 表示拷贝到哪个目录下,接受 file 类型,也接受字符串类型
    exclude {} // exclude 表示在拷贝的过程中,可以过滤拷贝的文件,exclude 中添加要排除的内容
    rename {} // rename 表示拷贝后将文件重命名
}
fileTree('app/build/outputs/apk/') { FileTree ft -> // fileTree() 文件树的操作 , 也是在 .gradle 文件的 Sync Now 的时候就会执行
    ft.visit { FileTreeElement element -> // 对文件树下的每个节点进行遍历 , FileVisitDetails 继承自 FileTreeElement
        println 'element.file : '+element.file.name
        copy {
            from element.file
            into rootProject.buildDir.path+'/test/' // 将apk下的文件拷贝到 ./build/test 下(不会拷贝节点下的目录,只会拷贝节点下的文件)
        }
    }
}

// 其他api: 依赖相关api 、 外部命令执行
buildscript { ScriptHandler scriptHandler -> // project的函数,闭包中传入的是 ScriptHandler 类型的参数
    scriptHandler.repositories { RepositoryHandler repositoryHandler -> // repositories 表示配置工程的仓库地址
        // 闭包中可不用 repositoryHandler. 而是直接调用函数是因为此闭包的delegate指向的就是repositoryHandler,闭包的this、owner、delegate中的成员,都可在闭包中直接调用
        jcenter() // 添加默认的 jcenter 仓库地址
        mavenCentral() // 添加 maven 仓库地址
        mavenLocal() // 添加本地 maven 仓库地址
//        ivy {} // 添加 ivy 仓库,这个Ant用的多,现在基本弃用了
        maven { MavenArtifactRepository mavenArtifactRepository -> // 添加私有的 maven 仓库地址, maven 地址可以配置多个
            name 'hj' // 仓库别名
            url 'http://localhost:8088:/xxx' // 仓库地址
            credentials { // 验证信息
                username = 'admin'
                password = 'admin'
            }
        }
    }
    // dependencies 表示配置工程的"插件"依赖地址(即在写gradle程序的时候需要用到的哪些第三方库), project对象中也有dependencies成员(指定应用中需要使用的第三方库)
    scriptHandler.dependencies { DependencyHandler DependencyHandler ->
        classpath 'com.android.tools.build:gradle:3.1.4' // 引入 gradle:3.1.4的库,并将此工程指定为android工程,还可以在指定为android的library
    }
}
//task(name: 'hjapkcopy') { // 使用此方式定义task,会报找不到。。。
task hjapkcopy {
    doLast { // doLast 中的内容会在Gradle的执行阶段执行,而不是配置阶段
        def srcPath = rootDir.path+"\\app\\build\\outputs\\apk"
        println "srcPath : $srcPath"
        def dstPath = 'E:\\gradle'
//        def command = "mv -f ${srcPath} ${dstPath}" // linux、mac中命令,移动文件
        def command = "move ${srcPath} ${dstPath}" // windows中的控制台命令,移动文件夹
        exec { // exec 为project提供的命令 去执行外部命令(即在cmd中执行)
            try {
//                executable 'bash' // executable 表示执行类型,只要是外部命令,executable都是固定的 bash (看linux、mac中shell的类型)
//                args '-c', command // -c 固定写法(linux、mac中)
                executable 'cmd.exe' // windows控制台
                args '/c', command // /c 固定写法(windows中)
                println 'command execute success.'
            } catch(GradleException e) {
                println 'command execute error.'
            }
        }
    }
}

app

// project api
this.hjgetParentPorjects()
def hjgetParentPorjects() { // 在子project中获取根project
    println "parent project is ${this.getParent().name}" // this.getParent().name()  表示获取父project ,如果在根project何种使用此函数,gradle构建时会报错
}

// 属性拓展
ext { // ext 是Project提供的扩展属性,Project类提供的成员属性是很少的,所以提供了 ext 给开发者拓展project的属性
    abcV = 12 // 为此project添加成员属性
}
// 12,haha,44,qw,1 , 使用时就当作是project对象的属性使用即可,rootProject 表示根project的对象,也可省略rootProject,直接 this.adcB 方式调用,因为子project继承自父project
println "${this.abcV},${this.abdA},${this.rootProject.adcB.map},${this.qweR},${this.eeR}"

// 其他api: 依赖相关api 、 外部命令执行
dependencies { // 指定应用依赖的库的方式主要有三种:本地文件(fileTree、file、files)、远程库、本地库(本地library、aar)
    // 表示添加当前project目录下的libs目录下所有节点文件后缀为 .jar 的文件 , 可以使用fileTree,也可使用file() files()
    implementation fileTree(dir: 'libs', include: ['*.jar'])
//    implementation('xxx') { // implementation('xxx') 等同于 implementation 'xxx'
//        // 假如某第三方库已经依赖了v4库,而要依赖的xxx库中也依赖了v4,gradle编译时会报重复依赖错误,使用 exclude 去除 xxx中的v4依赖
//        // 使用的是 key value 模型,key表示要排除的类型,value表示具体的
//        exclude module: 'support-v4'
//        exclude group: 'com.android.support' // group 表示去除 xxx库下所有 com.android.support 的包
//        transitive false // transitive 表示是否传递依赖,如果xxx库中依赖了库c,设为false的话,那么此应用中就不能使用库c的东西,默认false,不建议使用传递依赖
//    }
//    provided('xxxx') // provided 依赖的库只是在编译期间起作用(占位编译),依赖的库并不会像implementation一样打包到apk(jar、arr等输出)中
}

猜你喜欢

转载自blog.csdn.net/huanghuangjin/article/details/82318625