Android Gradle原理解釋

系列文章html

  1. Android Gradle原理解釋
  2. Android Studio點擊Run背後發生了什麼?

1. 前言

咱們都知道利用Android Studio編寫APP時,會使用Gradle這個工具,那麼Gradle究竟是什麼呢?它在APP編寫中起到什麼做用呢?java

Gradle是一個項目自動化建構工具。構建就是根據輸入信息執行一系列操做,最後獲得幾個產出物(APK包)。android

傳統的構建工具備Ant和Maven,但他們有一些缺點,例如Maven使用XML來制定構建規則。XML雖然通俗易懂,可是很難在xml中描述if{某條件成立,編譯某文件}/else{編譯其餘文件}這樣有不一樣條件的任務。針對這類問題天然須要編程來解決,因此,Gradle選擇了Groovy語言。編程

Gradle的另外一個特色是它是一種DSL(Domain-Specific-Language),即特定領域語言,就是針對某一領域而產生的語言。DSL的好處是一句話能夠包含不少意思,由於只針對特定領域解決問題。api

Gradle當前其支持的語言限於Java、Groovy和Scala,計劃將來將支持更多的語言。Gradle能夠幫你管理項目中的差別,依賴,編譯,打包,部署...,你能夠定義知足本身須要的構建邏輯,寫入到build.gradle中供往後複用,通俗的說:gradle是打包用的網絡

1.1 Groovy基礎

Groovy是個靈活的動態腳本語言,基於JVM虛擬機,語法和Java很類似,又兼容Java,且在此基礎上增長了不少動態類型和靈活的特性,如支持閉包和DSL。Groovy的開發環境配置能夠參考Groovy 環境配置,具體語言特性教程能夠參考-Groovy教程閉包

Groovy基於Java,又擴展了Java,運行過程當中首先會先將其編譯成Java類字節碼,而後經過JVM來執行這個Java類。app

1.2 Gradle介紹

Gradle是一個工具,也是一個編程框架。要弄清楚Gradle,則必須知道其組成的基本組件,Gradle中每一個待被編譯的工程叫Project,每一個Project在構建時都包含一系列Task,如Android Studio構建過程當中包括Java代碼編譯Task,資源編譯Task,Lint規則檢查Task,簽名Task等等。框架

參考深刻理解Android之Gradlemaven

配置Gradle環境前,確保已經安裝配置好Java環境,下載Gradle後解壓並配置環境變量,具體能夠參考-配置Gradle

下面是一個Gradle語言版的Hello word例子:

// Gradle版Hello word
// 新建build.gradle文件:
task hello{	// 定義一個任務Task名爲hello
    doLast{ // 添加一個動做Action,表示在Task執行完畢後回調doLast閉包中的代碼
        println'Hello World'//輸出字符串,單雙號都可
    }
}
// 命令行:
gradle hello // 執行build.gradle中名爲Hello的任務
// 輸出:
Hello World
複製代碼

總而言之,學習Gradle咱們須要掌握Groovy語言,以及Gradle在Android Studio中的工做方式,工做流程,工做原理。

2. Android studio中的Gradle文件

Android Studio 會使用高級構建工具包 Gradle 來自動執行和管理構建流程,同時也容許開發者定義靈活的自定義版本配置。每一個版本配置都可定義本身的一組代碼和資源,同時重複利用應用各個版本的共用部分。

Gradle提供了一種編譯、構建和打包 Android 應用或庫的靈活方式。 一個Android Studio和Gradle的項目目錄以下:

gradlelist.png

咱們先來看看Android Gradle項目中那些涉及到gradle的文件分別是什麼意思。

一個Android項目中全部文件的具體含義可參考Android開發者指南

2.1 Gradle wrapper(gradle包裝)

上圖中涉及到Gradle wrapper的部分以下所示,具體有上圖中的gradle文件夾,gradlew文件和gradlew.bat批處理文件

|--gradle
|   |--wrapper
|        |--gradle-wrapper.jar
|        |--gradle-wrapper.properties
|--gradlew
|--gradlew.bat
複製代碼

gradle文件夾中包含wrapper,wrapper顧名思義是對Gradle的一層包裝,便於在團隊開發過程當中統一Gradle構建的版本。

上面目錄中gradlewgradlew.bat分別是Linux和Windows下的可執行腳本,gradle-wrapper.jar是具體業務邏輯實現的jar包,gradlew可執行腳本最終仍是使用這個jar包來執行相關Gradle操做,gradle-wrapper.properties是配置文件,用於配置使用哪一個版本的Gradle,配置文件中的具體內容以下所示:

#Wed Jun 19 10:09:08 GMT+08:00 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
複製代碼

2.2 Settings.gradle (多工程配置)

此文件用於初始化以及工程樹的配置,大多數用於配置子工程,在Gradle中多個工程是經過工程樹來表示的,至關於咱們在Android Studio看到的Project和Module概念同樣,根工程至關於Project,子工程至關於Module,一個Project能夠有不少Module,一個子工程只有在Setting.gradle中配置了纔會生效。 配置舉例:

// 添加:app和:common這兩個module參與構建
include ':app' 
project(':app').projectDir = new File('存放目錄')
include':common'
project(':common').projectDir = new File('存放目錄')
複製代碼

若是不指定上述存放目錄,則默認爲是Settings.gradle其同級目錄。

2.3 build.gradle文件(版本文件)

每一個工程都會有build.gradle文件,該文件是該工程的構建入口,在此文件中能夠對該工程進行配置,如配置版本,插件,依賴庫等。 既然每一個工程都有一個build文件,那麼根工程也不例外,在根工程中能夠對子Module進行統一配置,全局管理版本號或依賴庫。 build文件分爲Project和Module兩種,以下圖所示:

build_gradle.png

  1. Project的build.gradle:整個Project的共有屬性,包括配置版本、插件、依賴庫等信息
  2. Module的build.gradle:各個module私有的配置文件

2.3.1 Project中build.gradle文件(頂層版本文件)

buildscript {
    // gradle腳本執行所需依賴倉庫
    repositories {
        google()
        jcenter()
        
    }
    // gradle腳本執行所需依賴
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.1'
    }
}

allprojects {
    // 項目自己須要的依賴倉庫
    repositories {
        google()
        jcenter()
        
    }
}
複製代碼

那麼buildscript中的repositories和allprojects的repositories的做用和區別是什麼呢?

  1. buildscript裏是gradle腳本執行所需依賴,分別是對應的maven庫和插件
  2. allprojects裏是項目自己須要的依賴,好比我如今要依賴maven庫的xx庫,那麼我應該將maven {url '庫連接'}寫在這裏,而不是buildscript中,不然找不到所須要的庫

參考 做者:CalvinNing -原文連接

2.3.2 Module中build.gradle文件(模塊級版本文件)

此部份內容參考下文中3.3.2節。

2.4 gradle.properties(屬性文件)

此文件主要在其中配置項目全局 Gradle 設置,如 Gradle 守護進程的最大堆大小。如需瞭解詳情,請參閱構建環境

3. Gradle插件

3.1 插件介紹

Gradle的設計很是好,自己提供一些基本的概念和總體核心的框架,其餘用於描述真實使用場景邏輯的都以插件擴展的方式來實現,好比構建Java應用,就經過Java插件來實現,那麼天然構建Android應用,就經過Android Gradle插件來實現。

Gradle 提供了不少官方插件,用於支持Java、Groovy等工程的構建和打包。同時也提供了自定義插件機制,讓每一個人均可以經過插件來實現特定的構建邏輯,並能夠把這些邏輯打包起來,分享給其餘人。

Android Gradle插件是基於內置的Java插件實現的。Gradle插件的做用以下:

  1. 能夠添加任務到項目,好比測試、編譯、打包
  2. 能夠添加依賴配置到項目,幫助配置項目構建過程當中須要的依賴,好比第三方庫等
  3. 能夠向項目中現有的對象類型添加新的擴展屬性和方法等,幫助配置和優化構建
  4. 能夠對項目進行一些約定,好比約定源代碼存放位置

3.2 插件種類及用法

3.2.1 插件種類

  • 二進制插件:實現了org.gradle.api.Plugin接口的插件,擁有plugin id,這個 id 是插件全局惟一的標識或名稱
  • 腳本插件:嚴格上只是一個腳本,即自定義的以 .gradle 爲後綴的腳本文件,能夠來自本地或網絡

3.2.2 插件用法

下面分別說下二進制插件和腳本插件的使用方法,

  • 二進制插件

id式:apply plugin:'plugin id'

類型式:apply plugin:org.gradle.api.plugins.JavaPlugin

簡寫式:apply plugin:JavaPlugin

  • 腳本插件apply from:'version.gradle'
  • 第三方發佈插件apply plugin:'com.android.application'

3.3 Android Gradle插件

從Gradle的角度看,Android其實就是Gradle的一個第三方插件,它是由Google的Android團隊開發的,Android 開發 IDE Android Studio 就採用 Gradle 構建項目。

3.3.1 Android Gradle插件分類

  1. App應用工程:生成可運行apk應用;插件id: com.android.application
  2. Library庫工程:生成AAR包給其餘的App工程公用,其使用方式和jar包同樣,裏面有相關的 Android 資源文件;插件id: com.android.library
  3. Test測試工程:對App應用工程或Library庫工程進行單元測試;插件id: com.android.test

3.3.2 Android Gradle插件的應用

主要來看下Android Gradle的build.gradle配置文件:

// 插件id
apply plugin:'com.android.application'
// 自定義配置入口,後續詳解
android{
    compileSdkVersion 23 // 編譯Android工程的SDK版本
    buildToolsVersion "23.0.1" // 構建Android工程所用的構建工具版本
	
    defaultConfig{
        applicationId "com.example.myapplication" // 配置包名
        minSdkVersion 14 // 最低支持的Android系統的Level
        targetSdkVersion 23 // 表示基本哪一個Android版本開發
        versionCode 1 // APP應用內部版本名稱
        versionName "1.0" // APP應用的版本名稱
    }
    buildTypes{
        release{ // 構建類型
            minifyEnabled false // 是否啓用混淆
            proguardFiles getDefaultPraguardFile('proguard-andrcid.txt'), 'proguard-rules.pro' // 配置混淆文件 } } } // 配置第三方依賴 dependencies{
   implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' } 複製代碼

android{}是Android Gradle插件提供的一個擴展類型,可讓咱們自定義Android Gradle工程。defaultConfig{}是默認的配置,是一個ProductFlavor(構建渠道),ProductFlavor容許咱們根據不一樣的狀況同時生成不一樣的APK包。buildTypes{}是一個NamedDomainObjectContainer類型,是一個域對象,能夠在buildTypes{}裏新增任意多個咱們須要構建的類型,好比debug類型。

NamedDomainObjectContainer具體能夠參考-NamedDomainObjectContainer詳解

3.3.3 多渠道構建

因爲發佈或者推廣APP的渠道不一樣,就形成了Android APP可能會有不少個,因此須要針對不一樣的渠道作不一樣的處理。 在Android Gradle中,定義了一個叫Build Variant(構建變體/構建產物)的概念,一個構建變體(Build Variant)=構建類型(Build Type)+構建渠道(Product Flavor),下面舉個例子:

  • Build Type有release、debug兩種構建類型
  • Product Flavor有baidu、google兩種構建渠道
  • Build Variant有baiduRelease、baiduDebug、googleRelease、googleDebug四種構件產物

配置好發佈渠道後,Android Gradle插件就會生成不少task,好比assembleBaidu,assembleRelease,assembleBaiduRelease

Gradle中一個原子性的操做叫作task,簡單理解爲task是Gradle腳本中的最小可執行單元。

  • assemble開頭的Task負責生成構件產物(Apk)
  1. assembleBaidu:運行後會生成baidu渠道的release和debug包
  2. assembleRelease:運行後會生成全部渠道的release包
  3. assembleBaiduRelease:運行後只會生成baidu的release包

4. Android Studio Gradle插件構建流程

4.1 Gradle生命週期

gradle_lifecycle.png

  1. Initialization(初始化階段):Gradle支持單項目和多項目構建。在初始化階段,Gradle肯定將要參與構建的項目,併爲每一個項目建立一個Project對象。通俗的說就是執行上述settings.gradle文件。
  2. Configuration(配置階段):在此階段,解析每一個Project中的build.gradle文件,並生成將要執行的task。
  3. Execution(執行階段):執行 task,進行主要的構建工做

4.2 APK構建流程

構建流程涉及許多將項目轉換成 Android 應用軟件包 (APK)的工具和流程,具體以下圖所示:

android_gradle_build.png

Android 應用模塊的構建流程一般按照如下步驟執行:

  1. 編譯器將您的源代碼轉換成 DEX 文件(Dalvik 可執行文件,其中包括在 Android 設備上運行的字節碼),並將其餘全部內容轉換成編譯後的資源
  2. APK 打包器將 DEX 文件和編譯後的資源合併到一個 APK 中。不過,在將應用安裝並部署到 Android 設備以前,必須先爲 APK 簽名。
  3. APK 打包器使用調試或發佈密鑰庫爲 APK 簽名
  • a. 若是構建的是調試版應用(即專用於測試和分析的應用),則打包器會使用調試密鑰庫爲應用簽名。Android Studio 會自動使用調試密鑰庫配置新項目。
  • b. 若是構建的是打算對外發布的發佈版應用,則打包器會使用發佈密鑰庫爲應用簽名
  1. 在生成最終 APK 以前,打包器會使用 zipalign 工具對應用進行優化,以減小其在設備上運行時所佔用的內存。

構建流程結束時,將得到應用的調試版 APK 或發佈版 APK,以用於部署、測試或發佈給外部用戶。

以上摘自Android開發者指南

行文至此,本文已大概理清Gradle的基本概念,以及其在Android Studio中的工做流程,但Android Studio中Gradle的工做具體細節還未解釋,如點擊Run圖標背後的Gradle的具體工做流程是什麼?這些會在後續博客中繼續分析。

相關文章
相關標籤/搜索