Gradle學習之五Project詳解

2020-10-18 20:00:52

系列文章目

Gradle學習之一入門介紹
Gradle學習之二Groovy核心語法
Gradle學習之三Groovy高階語法
Gradle學習之四Gradle生命週期
Gradle學習之五Project詳解
Gradle學習之六Task詳解
Gradle學習之七其他重要模組


前言

在這裡插入圖片描述

一、瞭解Project

在這裡插入圖片描述
雖然在專案中 AS有 Project 、 Module Library、Module App之分,但是對於Gradle來說,都是"project": 每一個module能把理解為gradle project的原因是存在build.gradle檔案
在這裡插入圖片描述
Root project 管理子project。子project負責本project的檔案輸出,並且能夠呼叫父project api ,管理其子project

二、Project核心api

在這裡插入圖片描述

2.1 相關API

在gradl專案中,每一個build.gradle會被編譯成Project位元組碼,因此在其中書寫內容,就相當於在Project類內部寫內容。
使用build.gradle列印所有的project和所有的子project:

this.getProjects()
//project api 詳解
//注意build.gradle中的方法,都是在設定階段執行的
//要想在執行階段執行, 需要設定task, 後面進行使用。
def getProjects(){
    println '---------------'
    println 'Root Project'
    println '---------------'
    this.getAllprojects().eachWithIndex { Project entry, int index ->
        if(index == 0){
            println "Root project ${entry.name}"
        }else {
            println "+--- project ${entry.name}"
        }
    }
}
this.getSubproject()
def getSubproject(){
    println '---------------'
    println 'Sub Project'
    println '---------------'
    this.getSubprojects().eachWithIndex { Project entry, int index ->
        println "+--- project ${entry.name}"
    }
}

使用build.gradle列印根project和父project:

this.getParentPro()
def getParentPro(){
    this.getParent().each {println it.name}
}

this.getRootPro()
def getRootPro(){
    println "The root is ${this.getRootProject().name}"
}

2.2 Project類常用API

在Android開發中,我們使用Gradle來設定和構建APP。接下來我們看一下Project的api在android專案中的應用。下述程式碼是寫在專案的根build.gradle下,為子模組提供一些通用設定。

/**
 * Project api
 *
 * 在根工程中管理子project (雖然能夠設定子project但是不建議這麼做)
 * 通過傳入模組名稱,獲取指定模組的Gradle Project物件,從而設定它
 */
project('app'){ Project project->
    apply plugin: 'com.android.application'
    group  'com.zfc'
    version '1.0.0'
    dependencies {}
    android{}
}

//該方法用於設定當前project和子project
allprojects {
    group 'com.zfc'
    version '1.0.0'
}

//列印驗證,是否子模組已經有上面設定的group屬性了
println project('app').group
println project('baselibrary').group

//不包括當前project,只包含它的子project
//比如將子project上傳的maven的設定,可以在這裡進行設定
subprojects { Project project->
    if(project.plugins.hasPlugin("com.android.library")){
        apply from: '../publicToMaven.gradle'
    }
}

三、屬性相關API

3.1 Project 預設屬性

public interface Project extends Comparable<Project>, ExtensionAware, PluginAware {
    //gradle預設檔名
    String DEFAULT_BUILD_FILE = "build.gradle";
    //預設路徑分隔符
    String PATH_SEPARATOR = ":";
  	//輸出的預設路徑
    String DEFAULT_BUILD_DIR_NAME = "build";
    String GRADLE_PROPERTIES = "gradle.properties";
}

3.2 定義擴充套件屬性

由於Project預設屬性有限。我們需要定義一些擴充套件屬性

//定義擴充套件屬性
ext{
}

subprojects{
	//每個project都定義了擴充套件屬性
	ext{
	}
}

我們可以在優化一下,將ext定義在根gradle中。根屬性,可以被子完全繼承,可以直接使用。

最佳實踐,將擴充套件屬性單獨這是在一個檔案中
在這裡插入圖片描述
然後再在根gradle參照。
在這裡插入圖片描述

3.3 定義擴充套件屬性二

還可以在gradle.properties.但是隻能定義key-value的形式

//file: gradle.properties
isNeedLoadTest = false

//file: setting.gradle
include ':app',"lib_base"
//需要注意的是gradle.properties的屬性 key或者value都是Object型別,需要進行一下轉換
if(hasProperty('isNeedLoadTest')?isNeedLoadTest.toBoolean():false){
	include ':test'
}

四、檔案屬性相關操作

在這裡插入圖片描述

4.1 檔案路徑api

println getRootDir().absoulutePath() //根工程
println getBuildDir().absolutePath()  //當前位置下的build資料夾路徑
println getProjectDir().absolutePath() //當前project模組

4.2 檔案定位

def getContent(String path){
	try{
		//file 從當前位置定位檔案
		//project 還有 files api ,通過批次定位檔案
		def f = file(path)
		return f.text
	}catch(GradleException e){
		e.printStackTrack()
	}
	return null
}

4.3 檔案拷貝

//將當前檔案的path複製都 根目錄下的build的檔案
copy{
	from fiile('path1')
	into getRootProject().getBuildDir()
	//還可以排除
	exclude{
	}
	//重新命名
	rename{
	}
}

4.4 檔案樹遍歷

fileTree('path'){FileTree fileTree ->
	fileTree.visit{ FileTreeElement element->
		copy{
			from element.file
			into getRootProject().getBuildDir().path+"/test"
		}
	}
}

上述的檔案操作,比如copy ,file等,需要在同一工程下進行操作。

五、其他API

在這裡插入圖片描述

5.1 依賴相關API

buildscript{ ScriptHandler scriptHandler->
	//設定工程的倉庫地址
	scriptHandler.repositories{ RepositoryHandler handler->
		handler.jcenter()
		handler.mavenCentral()
		handler.mavenLocal()
		handler.ivy{
		}
		handler.maven{
			name 'personal'
			url 'http://local.....'
			credenticals{
				username = 'admin'
				password = 'admin123'
			}
		}
	}
	//設定工程外掛地址
	scriptHandler.dependencies{
		classpath 'com.android.tools.buid:gradle:2.2.2'
		classpath 'com.tencent'
	}
}


dependencies{
	//資料夾 -> fileTree ,否則file
	compile fileTree(include:['*.jar'],dir:'libs') 
	compile(){
		//排除依賴
		exclude module:'xxx'
		exclude group:'yyyy'
		//禁止傳遞依賴
		transive false
	}
}

儘量不要使用傳遞依賴。因為傳遞依賴是不確定的。

compile 完全把依賴打包進去。
provided:輔助過程,確保不會再執行時起作用才可以。

5.2 外部命令執行

如果使用外部命令

task(name: 'apkcopy'){
	//doLast確保 該方法在gradle執行階段執行
	doLast{
		def sourcePath = this.buildDir.path + '/outputs/apk'
		def destPath = '絕對目的路徑'
		def cmd = 'mv -f ${sourcePath} ${destPath}'
		exec{
			try{
				executable 'bash'
				args '-c' , cmd
				println 'the command is execute success.'
			}catch(GradleException e){
				e.printStackTrace()
				println 'the command is execute failed.'
			}
		}
	}
}

./gradlew apkcopy