博客主頁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}" } } } }
若是個人文章對您有幫助,不妨點個贊鼓勵一下(^_^)