android中gradle的作用,Gradle 之 Android 中的應用

在上一篇文章中 Gradle 之語言基礎 Groovy 主要介紹了 Groovy 的基礎語法(如果沒有 Groovy 的基礎,建議先看看上篇文章,如果可以動手敲一下里面的示例代碼就更好不過了),也是為本篇文章打基礎的。

本篇文章主要介紹 Gradle 在 Android 中的應用(Android DSL 和 Gradle DSL),也是通過一些示例來介紹和理解,主要分為以下一些內容,示例代碼都在 GradleForAndroid

一. Gradle 構建生命周期

一個 Gradle 的構建通常有如下三個階段

初始化:項目 Project 實例會在該階段被創建。如果一個項目中包含有多個模塊,并且每一個模塊都有其對應的 build.gradle 文件,就會為每一個模塊都創建一個對應的 Project 實例

配置:執行各個模塊下的 build.gradle 腳本,為 Project實例創建和配置 Task,構造 Task 任務依賴關系圖以便在執行階段按照依賴關系執行 Task

執行:在這個階段將會決定執行哪個 Task,哪個 Task 被執行取決于開始該次構建的參數配置和該 Gradle 文件的當前目錄

在創建完成一個新的 Android 應用項目之后,一般情況下, .gradle 文件的目錄結構如下所示:

GradleForAndroid

|---- build.gradle

|---- setting.gradle

\---- app

\---- build.gradle

其中,兩個文件 build.gradle 和 setting.gradle 位于項目的根目錄下,還有一個 build.gradle 位于 \app\ 目錄下。\build.gradle 是頂層構建文件,\app\build.gradle 是模塊構建文件。

我們以上面這個新創建的項目來學習 Gradle 的構建生命周期

1.1 初始化

在初始化階段,會創建一個 Setting 對象,對應著 setting.gradle 文件,

Setting 對象的一個主要作用就是聲明哪些模塊將會參與到構建中去,Setting 文檔(Gradle API 5.0)

在新建的項目中,setting.gradle 文件一般會默認包含一行內容,如下所示

include ':app'

上面這一行,其實是一行 groovy 代碼的簡寫,對應的是 Setting#include(String[] projectPaths) 方法,表示 :app 模塊將會參與到構建中去。

如果我們創建一個 library 庫,setting.gradle 將會變為如下所示,表示 :app 和 :library 兩個模塊將會參與到構建中

include ':app', ':library'

setting.gradle 腳本文件可以中讀取一些只可讀的配置信息,這些配置信息的來源可以有如下三個:

可以在本工程的 gradle.properties 文件中定義配置信息

也可以在系統的 gradle.properties 文件中定義配置信息,系統的 gradle.properties 位于 user's .gradle 目錄下

還可以通過 -P 命令參數指定配置信息,比如 ./gradlew clean -P cmd='Hello from commandLine' 便在執行 clean task 的時候,指定了 cmd='Hello from commandLine' 配置信息

上面講到,一個 setting.gradle 文件對應著一個 Setting 對象,Setting 對象包含的方法如下圖所示

8b74e9cb5f08

Setting.png

例如有如下代碼

include ':app', ':library'

println propertiesFile

println DEFAULT_SETTINGS_FILE

println getRootProject().name

println getRootProject().path

getGradle().addBuildListener(new BuildListener() {

@Override

void buildStarted(Gradle gradle) {

println 'buildStarted'

}

@Override

void settingsEvaluated(Settings settings) {

println "settingsEvaluated"

}

@Override

void projectsLoaded(Gradle gradle) {

println 'projectsLoaded'

}

@Override

void projectsEvaluated(Gradle gradle) {

println 'projectsEvaluated'

}

@Override

void buildFinished(BuildResult result) {

println 'buildFinished'

}

})

其輸出是:

Hello from gradle.properties

settings.gradle

GradleForAndroid

:

settingsEvaluated

projectsLoaded

projectsEvaluated

BUILD SUCCESSFUL in 0s

3 actionable tasks: 3 executed

buildFinished

1.2 配置

在配置階段,會執行所有的 build.gradle,包括項目根目錄下的 build.gradle 和各個 module 下的 build.gradle

在執行 build.gradle 的時候,會為每個 build.gradle 創建一個對應的 Project 對象,Project 文檔(Gradle API 5.0)

配置階段會執行 build.gradle 里面的所有代碼和 Task 里面的配置代碼,比如下面的 printProperties Task,只執行了 doLast{} 之外的代碼,doLast{} 之外的代碼是 Task 的配置代碼

配置執行完成之后,會根據各個 Task 的依賴關系生成一個有向無環圖,可以通過Gradle對象的getTaskGraph方法訪問,對應的類為TaskExecutionGraph

在執行所有的 Gradle Task 之前,都會執行 初始化階段 和 配置階段 的代碼

比如有如下代碼

// Top-level build file where you can add configuration options common to all sub-projects/modules.

println "/build.gradle 開始配置"

buildscript {

println "/build.gradle buildscript 開始配置"

ext.kotlin_version = '1.2.71'

repositories {

google()

jcenter()

}

dependencies {

classpath 'com.android.tools.build:gradle:3.0.1'

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

// NOTE: Do not place your application dependencies here; they belong

// in the individual module build.gradle files

}

println "/build.gradle buildscript 結束配置"

}

allprojects {

println "/build.gradle allprojects 開始配置"

repositories {

google()

jcenter()

}

println "/build.gradle allprojects 結束配置"

}

task clean(type: Delete) {

delete rootProject.buildDir

}

ext {

local = 'Hello from build.gradle'

}

task printProperties {

println "/build.gradle task printProperties 開始配置"

println '/build.gradle task printProperties'

println "/build.gradle task printProperties 結束配置"

doLast {

println local

println propertiesFile

if (project.hasProperty('cmd')) {

println cmd

}

}

}

println "/build.gradle 結束配置"

在 Terminal 里面執行 ./gradlew clean 會有如下輸出

Hello from gradle.properties

settings.gradle

GradleForAndroid

:

settingsEvaluated

projectsLoaded

// 配置階段,執行 /build.gradle 里面的代碼

> Configure project :

/build.gradle buildscript 開始配置

/build.gradle buildscript 結束配置

/build.gradle 開始配置

/build.gradle allprojects 開始配置

/build.gradle allprojects 結束配置

/build.gradle allprojects 開始配置

/build.gradle allprojects 結束配置

/build.gradle allprojects 開始配置

/build.gradle allprojects 結束配置

/build.gradle task printProperties 開始配置

/build.gradle task printProperties

/build.gradle task printProperties 結束配置

/build.gradle 結束配置

projectsEvaluated

BUILD SUCCESSFUL in 0s

3 actionable tasks: 3 executed

buildFinished

1.3 執行

執行階段就是指執行某個具體的任務 Task。說道 Task,我想大家應該比較熟悉,在 Android 項目中依賴了 Android Gradle 插件以后,會有許多自帶的 Task,比如常用的 clean、assemble 等,而且大家更應該掌握的是如何自定義 Task,關于 Task 會單獨抽一節來講述。

二. 自定義 Task

任務 Task 代表了在構建過程中的一個單原子性的動作,比如:編程生成 .class 文件或者生成 javadoc 等.

每一個 task 都是屬于某一個 Project 對象的,每一個 task 都有自己的名字,在 project 中 task 的名字是唯一的,如果在整個項目 projects 范圍內需要指定某個 task 的話,也需要指定 project 的名字,project 和 task 的名字中間使用 : 相連接,比如:./gradlew :app:clean

創建 Task 對象的方法有以下幾種

// 通過 TaskContainer.create(String) 創建 `Task`

getTasks().create('helloTask') {

doLast {

println 'create Task by TaskContainer'

}

}

task helloTask1 {

doLast {

println 'create Task by task(String name)'

}

}

class HelloTask extends DefaultTask {

def message = 'create Task by extends DefaultTask'

@TaskAction

def hello() {

println message

}

}

// 通過 type 參數可以指定該 task 的父類,默認的父類是 DefaultTask

task helloTask2(type: HelloTask)

一個 Task 是由一系列的 Action 組成的,當一個 Task 執行的時候就是按照一定的順序執行這些 Action,可以有以下兩種方式向 Task 中添加 Action

通過閉包 Closure 的方式添加 Action

class HelloTask extends DefaultTask {

def message = 'create Task by extends DefaultTask'

@TaskAction

def hello() {

println message

}

}

task helloTask2(type: HelloTask) {

doFirst {

println 'helloTask2 doFirst'

}

doLast {

println 'helloTask2 doLast'

}

}

直接添加 Action 實例對象

def taskDef = task helloTask3(type: HelloTask)

taskDef.doFirst(new Action() {

@Override

void execute(Task task) {

println 'helloTask3 Action execute doFirst'

}

})

taskDef.doLast(new Action() {

@Override

void execute(Task task) {

println 'helloTask3 Action execute doLast'

}

})

Task 依賴關系 & Task 執行順序

在 Task 中有兩個很重要的概念 dependsOn 和 mustRunAfter。dependsOn 用于聲明兩個 Task 對象之間的依賴關系,mustRunAfter 用于聲明一個 Task 必須在另一個 Task 之后運行,雖然感覺差不多,但是實際上還是有區別的

helloTaskB.dependsOn(helloTaskA) 中,可以單獨運行 helloTaskA,但是運行 helloTaskB 的時候會觸發 helloTaskA 的執行

helloTaskC.mustRunAfter(helloTaskA)中,helloTaskA 和 helloTaskC 都是可以單獨運行的,但是當 helloTaskC 和 helloTaskA 同時運行時,helloTaskC 一定會在 helloTaskA 之后運行

task helloTaskA {

doFirst {

println 'helloTaskA doFirst'

}

}

task helloTaskB {

doFirst {

println 'helloTaskB doFirst'

}

}

helloTaskB.dependsOn(helloTaskA)

task helloTaskC {

doFirst {

println 'helloTaskC doFirst'

}

}

helloTaskC.mustRunAfter(helloTaskA)

Android 中使用自定義 Task

在 Gradle 構建的時候,需要將自定義的 Task 添加到構建過程中時,需要把握好添加自定義 Task 的時機與位置

下面一幅圖清晰地展示了 Gradle 構建過程中一些關鍵的回調,可以在下面一些回調中添加自定義 Task

在 project 對象中,可以通過 gradle 對象得到 TaskExecutionGraph 的實例對象,也可以通過 TaskExecutionGraph 實例對象一些關鍵回調添加自定義的 Task。比如下面這個例子,就是在 TaskExecutionGraph 實例對象準備好之后,彈出一個 dialog 用于輸入 storePass 和 keyPass,然后將 storePass 和 keyPass 設置到 android.signingConfigs 中

apply plugin: 'com.android.application'

import groovy.swing.SwingBuilder

//......

gradle.taskGraph.whenReady { taskGraph ->

if (taskGraph.hasTask(':app:assembleRelease')) {

def storePass = ''

def keyPass = ''

if (System.console() == null) {

System.setProperty('java.awt.headless', 'false')

new SwingBuilder().edt {

dialog(modal: true, title: 'Enter password', alwaysOnTop: true, resizable: false, locationRelativeTo: null, pack: true, show: true) {

vbox { // Put everything below each other

label(text: "Please enter store passphrase:")

def input1 = passwordField()

label(text: "Please enter key passphrase:")

def input2 = passwordField()

button(defaultButton: true, text: 'OK', actionPerformed: {

storePass = input1.password;

keyPass = input2.password;

dispose();

})

}

}

}

} else {

storePass = System.console().readPassword("\nPlease enter store passphrase: ")

keyPass = System.console().readPassword("\nPlease enter key passphrase: ")

}

if (storePass.size() <= 0 || keyPass.size() <= 0) {

throw new InvalidUserDataException("You must enter the passwords to proceed.")

}

storePass = new String(storePass)

keyPass = new String(keyPass)

android.signingConfigs.release.storePassword = storePass

android.signingConfigs.release.keyPassword = keyPass

}

}

如下圖所示 TaskExecutionGraph 的方法結構如下圖所示,都是非常實用方便的方法

8b74e9cb5f08

TaskExecutionGraph.png

三. Android DSL & Gradle DSL

3.1 Android DSL

Android DSL 是 Gradle 的一個 Android 插件,其實在使用 Android Studio 開發的時候經常會和 Android DSL 打交道,比如下面 android{ } 閉包 里面的內容都是 Android DSL

apply plugin: 'com.android.application'

import groovy.swing.SwingBuilder

android {

compileSdkVersion 27

defaultConfig {

applicationId "com.lijiankun24.gradleforandroid"

minSdkVersion 15

targetSdkVersion 27

// ......

}

buildTypes {

// ......

}

signingConfigs {

// ......

}

}

至于里面都有哪些 API,可以去 Android DSL 文檔 查看,也可以去 GitHub 上面搜 android-gradle-dsl

3.2 Gradle DSL

Gradle DSL 在上面介紹 Gradle 生命周期和自定義 Task 的時候已經介紹過了,比如上面介紹的 Setting 和 TaskExecutionGraph 都是 Gradle DSL 中的類,其他的類和方法等 API 可以去 Gradle DSL 文檔 查看,或者可以在 Android Studio 中像查看 Android SDK 源碼一樣去查看 Gradle DSL 的源碼

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530826.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530826.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530826.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

android程序更改pdf文件格式,Android根據pdf模板生成pdf文件

1 public voidFillPdfTemplate(String id) {2 android.icu.text.SimpleDateFormat simpleDateFormat 3 new android.icu.text.SimpleDateFormat("HHmmss");//HH:mm:ss4 //設置默認時區5 simpleDateFormat.setTimeZone(android.icu.util.TimeZone.getTimeZone("G…

android頁面跳轉時獲取地址欄,Android 利用scheme頁面內跳轉協議進行跳轉

什么是 URL Scheme&#xff1f;android中的scheme是一種頁面內跳轉協議。通過定義自己的scheme協議&#xff0c;可以非常方便跳轉app中的各個頁面&#xff1b;通過scheme協議&#xff0c;服務器可以定制化告訴App跳轉到APP內部頁面。之前項目都是我們客戶端和服務器端用自定義j…

android按鈕置于頂層,如何把按鍵顯示在最頂層窗口上(屏幕最頂上)

[Delphi] 純文本查看 復制代碼unit Unit2;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;typeTForm2 class(TForm)procedure FormCreate(Sender: TObject);private{ …

android signalr 自動重連,.net-何時在signalR中重新連接?

當客戶端脫機然后不久后重新獲得連接時&#xff0c;就會發生集線器重新連接。 SignalR配置值在很大程度上決定了以下示例的時間戳&#xff0c;因此無需逐字記錄時間。以下是一些示例及其涉及重新連接行為的結果(時間格式&#xff1a;m&#xff1a;ss)&#xff1a;當我提到以下內…

自己寫的android apk反編譯,獲取Android自己寫好了的apk以及反編譯

今天&#xff0c;我們先說一下&#xff0c;獲取Android自帶的apk以及反編譯它們來學習Android工程師是怎樣寫的&#xff0c;今天我們就以拿到Android自帶的短信管理器的apk為例子你可能有疑問&#xff0c;為什么要那么麻煩&#xff0c;從系統來拿&#xff0c;還要反編譯&#x…

一加7pro系統更新android10,一加OnePlus7T Pro官方安卓10.0穩定版出廠系統固件升級更新包...

咱們的這個一加OnePlus7T Pro手機的最新穩定版系統包也是在這里來分享一下了&#xff0c;這個穩定版本的系統包是安卓10穩定版的&#xff0c;也是第一個版本的&#xff0c;系統包大小是3.2G&#xff0c;系統方面主要是全新的UI設計&#xff0c;輕快流暢操作體驗&#xff0c;更多…

5元素升級android6,升級你的app以支持高長寬比的新旗艦

為了呈現更好的視覺效果&#xff0c;許多安卓OEM廠商都開始采用超大屏幕。三星剛剛發布了自己的新旗艦Samsung Galaxy S8&#xff0c;長寬比達到18.5:9。今年早些時候的全球移動大會上LG也亮相了 LG G6&#xff0c;屏幕長寬比達到了18:9。(左) maximum aspect ratio為16:9的app…

CCS太陽光準直系統使用積分球均勻光源

CCS太陽光準直系統的應用范圍廣泛&#xff0c;包括太陽光輻射測量、光學遙感儀器研制與標定、均勻光源的推廣使用等方面。通過使用CCS太陽光準直系統&#xff0c;可以準確地模擬太陽光&#xff0c;并對各種光學儀器進行校準和標定&#xff0c;從而提高測量精度和穩定性。 CCS太…

js怎么制作html的主題,用HTML和CSS以及JS制作簡單的網頁菜單界面的代碼

寫ABROAD項目用到了標簽這個東東&#xff0c;其實標簽在WEB上到處可見&#xff0c;圖中就依次顯示了DCC文章發布器、ABROAD后臺添加數據、百度圖片搜索、sf發布博客文章時貼標簽的樣式——標簽就像瀏覽器里原生的checkbox一樣&#xff0c;不過checkbox實在太丑了&#xff0c;就…

登錄界面轉換實現html,HTML+CSS系列:登錄界面實現

font-face{font-family:"iconfont";src:url(iconfont.eot?t1601708272399); /*IE9*/src:url(iconfont.eot?t1601708272399#iefix) format(embedded-opentype),/*IE6-IE8*/url(data:application/x-font-woff2;charsetutf-8;base64,d09GMgABAAAAAARUAAsAAAAACIAAAAQI…

html文檔基本結構由哪三對,第3章 網頁制作及HTML語言基本結構簡介.ppt

第三章 網頁制作與HTML語言基本結構簡介 本章提要 靜態網頁與動態網頁 Dreamweaver MX制作網頁 HTML語言的基本結構 3.1網頁制作概述 3.1.1靜態網頁與動態網頁 1.靜態網頁 由超級文本標志語言HTML的標志代碼構成&#xff1b; 用記事本、FrontPage、Dreamweaver、Fireworks可以制…

嗶哩網站登錄界面html代碼,仿嗶哩嗶哩網頁模板設計

【實例簡介】【實例截圖】【核心代碼】bilibili├── Home.html├── Login.html├── Register.html├── css│ ├── bootstrap.min.css│ └── css.css├── forget the password.html├── img│ ├── 001.png│ ├── 002.png│ ├── 003.png│ …

2021高考成績查詢大連,2021年大連高考各高中成績及本科升學率數據排名及分析...

一、大連高考各高中成績及本科升學率數據2020年遼寧省普通高等學校招生文化課錄取控制分數線普通類 文史特殊類型招生控制分數線&#xff1a;567分本科控制分數線&#xff1a;472分專科(高職、提前專科)控制分數線&#xff1a;150分普通類 理工特殊類型招生控制分數線&#x…

編寫了html怎么測試,如何將測試結果寫入HTMLTestRunner生成的報告標題中

HTMLTestRunner生成測試報告時&#xff0c;報告的標題在運行前就已經寫死在代碼了&#xff0c;假如我現在需要在執行完畢后&#xff0c;根據執行結果&#xff0c;把執行的狀態寫在標題里面&#xff0c;類似的效果如圖&#xff1a;標題如果有一條執行錯誤的&#xff0c;就在后面…

計算機基本的應用是,計算機統考應用基礎練習題

計算機統考應用基礎練習題計算機統考就要來臨&#xff0c;有哪些好的練習試題。下面是小編為您整理的關于計算機統考應用基礎練習題的相關資料&#xff0c;歡迎閱讀&#xff01;計算機安全的基本知識和概念1、下面最難防范的網絡攻擊是______。A、計算機病毒B、假冒C、修改數據…

編碼 data text html c,誰說前端不需要懂二進制

作者&#xff1a;全棧成長之路 公號 / 山月行作為一名前端&#xff0c;在工作中也會遇到很多有關二進制處理的需求&#xff0c;如 EXCEL 表格的導出&#xff0c;PDF 的生成&#xff0c;多個文件的打包&#xff0c;音頻的處理。從前后端整體上來說前端代表 UI 層&#xff0c;它的…

計算機動漫與游戲制作專業大學有哪些,西安鐵道職業學校計算機動漫與游戲制作專業從事什么工作?...

西安鐵道職業學校坐落于陜西省西安市灞橋區朝陽工業園&#xff0c;占地400余畝&#xff0c;總建筑面積30余萬平方米&#xff0c;學校緊鄰火箭軍工程大學(二炮學院)。學校建有多功能軌道教學大樓、電子閱覽室、軌道綜合實訓樓、室外軌道實訓基地、乘務形體訓練中心等先進教學設施…

小學四年級計算機制作月歷教案,四年級上冊信息技術教案-1制作月歷|冀教版(5頁)-原創力文檔...

制作月歷教學目標&#xff1a;1、認識Word&#xff0c;學會美化月歷。2、鍛煉學生協同合作解決問題的能力。3、培養學生探究問題的能力,在制作月歷的過程中體驗學習的樂趣。學情分析&#xff1a;本課主要任務是安排學生利用word文檔制作一張月歷&#xff0c;在此之前&#xff0…

計算機聯用測定無機鹽溶解熱測試題,計算機聯用測定無機鹽溶解熱

計算機聯用測定無機鹽溶解熱計算機聯用測定無機鹽溶解熱一 實驗目的1. 用量熱計測定KCl的積分溶解熱。2. 掌握量熱實驗中溫差校正方法以及與計算機聯用測量溶解過程動態曲線的方法。二 實驗原理鹽類的溶解過程通常包含著兩個同時進行的過程&#xff1a;晶格的破壞和離子的溶劑化…

通過微型計算機的電流,單板微型計算機控制的電流型變頻調速系統

單板微型計算機控制的電流型變頻調速系統介紹用8位單板微型計算機控制的電流型變頻調速系統。系統利用軟件實(本文共4頁)閱讀全文>>空間矢量脈寬調制(SVPWM)技術運用于變頻調速系統具有直流電壓利用率高,功率器件的開關損耗小,電流諧波抑制效果好等明顯優勢。本文給出了一…