博客主页java
在讲解Task以前,先了解Gradle核心之Project详解及实战android
查看全部的Project,在Gradle中为咱们提供了Task任务projects,执行下面命令后,会列出全部的Projectsegmentfault
> gradlew projects // 执行上面命令后,列出全部的project,包括Root project ------------------------------------------------------------ Root project ------------------------------------------------------------ Root project 'walletApp' \--- Project ':app
咱们能够经过Project提供的API访问全部的project。getAllprojects返回全部的project,包括当前project,返回类型:Set集合bash
def getMyAllProjects() { println "-------------------------------------" println "Root Project" println "-------------------------------------" // 获取全部project,包括自己 this.getAllprojects().eachWithIndex { Project project, int index -> if (index == 0) { println "Root Project: ${project.name}" } else { println "+---- Project: ${project.name}" } } }
也提供了getSubprojects返回全部子project,返回类型:Set集合闭包
def getMySubprojects() { println "-------------------------------------" println "Sub Project" println "-------------------------------------" // 获取全部子project this.getSubprojects().eachWithIndex { Project project, int index -> println "+---- Project: ${project.name}" } }
除了上面两种方式,还提供了获取 Parent project和 Root project ,对应的方法分别是getParent() 和 getRootProject()。他们主要区别是,getParent()若是自己就是Root Project,则返回null;而getRootProject()若是自己就是Root Project,返回Root project,不会返回nullapp
/** * 获取父Project, 若是自己就是Root Project,返回null */ def getMyParentProject() { // The parent project, or null if this is the root project. if (this.getParent()) { println "the parent project name is : ${this.getParent().name}" } else { println "the parent project is null" } } /** * 获取Root Project,若是自己就是Root Project,返回本身,不会返回null */ def getMyRootProject() { // The root project. Never returns null. def name = this.getRootProject().name println "the root project name is: ${name}" }
能够在Root project中经过Project提供的project方法对单个project进行独立配置,如应用插件、project分组、project版本、依赖等信息maven
project('app') { Project project -> project.apply plugin: 'com.android.application' project.group 'com.yqb.mm' project.version '1.0.0' project.dependencies { } }
每一个Project都会有一个Build文件,能够经过Project提供的subprojects 或者 allprojects 能够对Child Project统一配置gradle
this.subprojects { println "The project name is ${project.name}" } // 输出日志信息 The project name is app The project name is basiclib
Project默认提供下面几种属性,从下图中能够看出,为何gradle中build文件名是build.gradle了。ui
除了Project默认提供的,咱们也能够经过ext关键字自定义属性。下面是咱们自定义的应用包名、版本信息、依赖、签名文件等相关信息。this
ext { applicationId = "com.kerwin.test" // android sdk version // 使用以下: // def versions = rootProject.ext.versions // compileSdkVersion versions.compileSdkVersion // buildToolsVersion versions.buildToolsVersion versions = [ compileSdkVersion: 26, minSdkVersion : 19, targetSdkVersion : 26, versionCode : 182, versionName : '1.8.2', ] // dependencies // 使用以下: // def dependencies = rootProject.ext.dependencies // compile dependencies.support.appcompat dependencies = [ support : [ appcompat : "com.android.support:appcompat-v7:26.1.0", constraint: "com.android.support.constraint:constraint-layout:1.1.3", design : "com.android.support:design:26.1.0" ], gson : "com.google.code.gson:gson:2.8.5" ] signingConfigs = [ debug: [ storeFile : '../keystore/mm_debug.keystore', storePassword: 'pa123456', keyAlias : 'mm_key', keyPassword : 'pa123456', ] ] }
除了上面方式自定义属性外,还能够在gradle.properties文件中定义,但只能是简单的Key-Value形式.
在gradle.properties文件中自定义以下属性:
// gradle.properties TINKER_ENABLE=true
例如能够在settings.gradle文件中根据在gradle.properties文件中定义的属性作一些操做
if (hasProperty('TINKER_ENABLE') ? Boolean.parseBoolean(TINKER_ENABLE) : false) { println "TINKER_ENABLE 打开了." } else { println "TINKER_ENABLE 关闭了." } // 当TINKER_ENABLE=true,输出日志信息 TINKER_ENABLE 打开了.
在Project中提供了不少获取文件路径的方法,如:getProjectDir(),getRootDir(),getBuildDir()
// Root project的根目录路径 println "the root directory of this project, ${project.getRootDir().absolutePath}" // 当前project的build文件路径 println "the build directory of this project, ${project.getBuildDir().absolutePath}" // 当前project的目录路径,若是当前project是Root project,等同于getRootDir() println "The directory containing the project build file, ${project.getProjectDir().absolutePath}" // 输出的日志信息 the root directory of this project, D:\work\yqb.com\newCode\merchantApp the build directory of this project, D:\work\yqb.com\newCode\merchantApp\build The directory containing the project build file, D:\work\yqb.com\newCode\merchantApp
println getContent('settings.gradle') def getContent(String path) { try { def file = file(path) return file.text } catch (Exception ex) { println "getContent has error: ${ex.getMessage()}" return "" } }
Project为咱们提供了简便的方法copy对文件进行拷贝。
def copyApk() { this.copy { // srcApkDir>>> D:\work\yqb.com\newCode\merchantApp\app\build\bakApk // destApkDir>>> D:\work\yqb.com\newCode\merchantApp\build\apk // from 用于指定拷贝的源文件或者文件夹 from file("${buildDir}/bakApk/") // into 用于指定拷贝的目的地 into file("${getRootProject().getBuildDir().path}/apk") } }
除了使用from 和 into 指定源路径和目的地以外,还能够配置拷贝后使用rename文件从新命名、exclude移除不需拷贝的文件等。
def copyApk() { this.copy { // srcApkDir>>> D:\work\yqb.com\newCode\merchantApp\app\build\bakApk // destApkDir>>> D:\work\yqb.com\newCode\merchantApp\build\apk // 指定拷贝的源文件或者文件夹 from file("${buildDir}/bakApk/") // 指定拷贝的目的地 into file("${getRootProject().getBuildDir().path}/apk") // 移除不须要拷贝的文件, 例如:不拷贝以txt结尾的文件 //exclude "**/*.txt" // 也可使用闭包,移除不须要拷贝的文件 exclude { details -> println "exclude>>> file: ${details.file}" return details.file.name.endsWith('.txt') } // 从新命名拷贝的文件名 rename { String fileName -> println "rename>> fileName: ${fileName}" fileName.replace("app-arm-debug.apk", "test.apk") } } }
Project提供的fileTree方法,能够将指定文件目录下全部的文件封装成文件树对象操做
fileTree("build/outputs/apk") { ConfigurableFileTree fileTree -> fileTree.visit { FileVisitDetails details -> println "The file name is ${details.file}" copy { from details.file into "${getRootProject().getBuildDir().path}/apk" exclude { file -> return file.file.isDirectory() } } } }
Project提供了依赖相关的API,如 buildscript
buildscript { repositories { maven { url "http://maven.aliyun.com/nexus/content/groups/public/" } jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.alibaba:arouter-register:1.0.2' classpath("com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}") { changing = TINKER_VERSION?.endsWith("-SNAPSHOT") exclude group: 'com.android.tools.build', module: 'gradle' } } }
可使用Project提供的javaexec 或者 exec 执行一个外部命令。使用外部命令实现一个copy功能
tasks.create(name: 'copyAPK') { doLast { def srcFilePath = this.buildDir.path + "/outputs/apk" def destFilePath = this.buildDir.path + "/outputs/backup" def command = "mv -f ${srcFilePath} ${destFilePath}" exec { ExecSpec execSpec -> try { executable 'bash' args '-c', command } catch (Exception ex) { println "copyAPK>>> error: ${ex}" } } } }
若是个人文章对您有帮助,不妨点个赞鼓励一下(^_^)