主頁 > 移動端開發 > Gradle進階計劃(一)Gradle初探

Gradle進階計劃(一)Gradle初探

2021-01-25 11:34:04 移動端開發

相信對于任何一位安卓開發工程師來說,Gradle一定不陌生,但是很多人甚至是很多年開發經驗的高級工程師對Gradle仍然不甚了解,市面上涉及Gradle的文章大多數講解的也不是很系統,本專欄旨在系統的梳理下Gradle的相關知識點,希望能對你有所幫助,

一、什么是 Gradle

“Gradle is an open-source build automation system that builds upon the concepts of Apache Ant and Apache Maven and introduces a Groovy-based domain-specific language (DSL) instead of the XML form used by Apache Maven for declaring the project configuration.[1] Gradle uses a directed acyclic graph ("DAG") to determine the order in which tasks can be run.”——維基百科對Gradle的定義,

翻譯過來就是:“Gradle是一個基于Apache Ant和Apache Maven概念的專案自動化構建開源工具,它使用一種基于Groovy的特定領域語言(DSL)來宣告專案設定,拋棄了基于XML的各種繁瑣配置,”

可以從三個角度來理解:

1. Gradle 是一個自動化構建工具

Gradle 是通過組織一系列 Task 來最終完成自動化構建的,以生成一個可用的 apk 為例,整個程序要經過 資源的處理,javac 編譯,dex 打包,apk 打包,簽名等步驟,每個步驟就對應到 Gradle 里的一個 Task,

2. 撰寫 Gradle 腳本可以使用 Groovy 或者 Kotlin DSL

Gradle 腳本 使用 Groovy 或者 Kotlin 撰寫,不過目前還是 Groovy 居多,DSL 也就是 Domain Specific Language 的簡稱,是為了解決某一類任務專門設計的計算機語言,與 GPL(General-Purpose Language,比如 Java) 相比起來,DSL 使用簡單,定義比較簡潔,比起組態檔,DSL 又可以實作語言邏輯,對 Gradle 腳本來說,他實作了簡潔的定義,又有充分的語言邏輯,以 android {} 為例,這本身是一個函式呼叫,引數是一個閉包,但是這種定義方式明顯要簡潔很多,

3. Gradle 基于 Groovy 撰寫,而 Groovy 是基于 JVM 語言

Gradle 使用 Groovy 撰寫,Groovy 是基于 JVM 的語言,所以本質上是面向物件的語言,面向物件語言的特點就是一切皆物件,所以,在 gradle 里,.gradle 腳本的本質就是類的定義一些配置項的本質都是方法呼叫,引數是后面的 {} 閉包,比如 build.gradle 對應 Project 類,buildScript 對應 Project.buildScript 方法

二、Gradle 專案層次

(一)setting.gradle

settings.gradle 是負責配置專案的腳本,對應 Settings 類,Gradle 構建程序中,會根據 settings.gradle 生成 Settings 的物件,

其中幾個主要的方法有:

  • include(projectPaths) //子模塊參考
  • include(projectDir)
  • includeFlat(projectNames) //平級參考
include ':app'
//指定子模塊的位置,使用 project 方法獲取 Project 物件,設定其 projectDir 引數
project(':app').projectDir = new File('./app')

(二)rootproject/build.gradle

build.gradle 負責整體專案的一些配置,對應的是 Project 類,gradle 構建的時候,會根據 build.gradle 生成 Project 物件,Project 其實是一個介面,真正的實作類是 DefaultProject,

其中幾個主要方法有:

  • buildscript // 配置腳本的 classpath
  • allprojects // 配置專案及其子專案
  • respositories // 配置倉庫地址,后面的依賴都會去這里配置的地址查找
  • dependencies // 配置專案的依賴
buildscript { // 配置專案的 classpath
    repositories {  // 專案的倉庫地址,會按順序依次查找
        google()
        jcenter()
        mavenLocal()
    }
    dependencies { // 專案的依賴
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.zy.plugin:myplugin:0.0.1'
    }
}

allprojects { // 子專案的配置
    repositories {
        google()
        jcenter()
        mavenLocal()
    }
}

(三)module/build.gradle

build.gradle 是子專案的配置,對應的也是 Project 類
子專案和根專案的配置是差不多的,不過在子專案里可以看到有一個明顯的區別,就是參考了一個插件 apply plugin "com.android.application",后面的 android dsl 就是 application 插件的 extension,關于 android plugin dsl 可以看 android-gradle-dsl(需要科學上網),
其中幾個主要方法有:

  • compileSdkVersion // 指定編譯需要的 sdk 版本
  • defaultConfig // 指定默認的屬性,會運用到所有的 variants(構建變體)
  • buildTypes // 配置編譯屬性
  • productFlavor // 配置專案的 flavor
apply plugin: 'com.android.application' // 引入 android gradle 插件

android { // 配置 android gradle plugin 需要的內容
    compileSdkVersion 26
    defaultConfig { // 版本,applicationId 等配置
        applicationId "com.zy.easygradle"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
    }
    buildTypes { 
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions { // 指定 java 版本
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }

    // flavor 相關配置
    flavorDimensions "size", "color"
    productFlavors {
        big {
            dimension "size"
        }
        small {
            dimension "size"
        }
        blue {
            dimension "color"
        }
        red {
            dimension "color"
        }
    }
}

// 專案需要的依賴
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar']) // jar 包依賴
    implementation 'com.android.support:appcompat-v7:26.1.0' // 遠程倉庫依賴
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation project(':module1') // 專案依賴
}

(四)gradle wrapper

gradlew / gradlew.bat 這個檔案用來下載特定版本的 gradle 然后執行的,就不需要開發者在本地再安裝 gradle 了,

這樣做有什么好處呢?開發者在本地安裝 gradle,會碰到的問題是不同專案使用不同版本的 gradle 怎么處理,用 wrapper 就很好的解決了這個問題,gradle wrapper 一般下載在 GRADLE_CACHE/wrapper/dists 目錄下,

gradle/wrapper/gradle-wrapper.properties 是一些 gradlewrapper 的配置,其中用的比較多的就是 distributionUrl,可以執行 gradle 的下載地址和版本,
gradle/wrapper/gradle-wrapper.jar 是 gradlewrapper 運行需要的依賴包,

(五)gradle init

在 gradle 里,有一種 init.gradle 比較特殊,這種腳本會在每個專案 build 之前先被呼叫,可以在其中做一些整體的初始化操作,比如配置 log 輸出等,
使用 init.gradle 的方法:

  1. 通過 --init-script 指定 init.gradle 位置 eg: gradlew --init-script initdir/init.gradle
  2. init.gradle 檔案放在 USER_HOME/.gradle/ 目錄下
  3. .gradle 腳本放在 USER_HOME/.gradle/init.d/ 和 GRDALE_HOME/init.d/ 目錄下

三、Gradle 生命周期

Gradle 構建分為三個階段:
1. 初始化階段
初始化階段主要做的事情是決議 settings.gradle 來獲取模塊資訊,明確有哪些專案需要被構建,然后為對應的專案創建 Project 物件,

2. 配置階段
配置階段主要做的事情是對上一步創建的專案進行配置,這時候會執行 build.gradle 腳本,并且會生成要執行的 Task,

3. 執行階段
執行階段主要做的事情就是執行 Task,進行主要的構建作業,

四、Gradle 依賴

在 gradle 3.4 里引入了新的依賴配置,如下:

新配置棄用配置行為作用
implementationcompile依賴項在編譯時對模塊可用,并且僅在運行時對模塊的消費者可用, 對于大型多專案構建,使用 implementation 而不是 api/compile 可以顯著縮短構建時間,因為它可以減少構建系統需要重新編譯的專案量, 大多數應用和測驗模塊都應使用此配置,implementation 只會暴露給直接依賴的模塊,使用此配置,在模塊修改以后,只會重新編譯直接依賴的模塊,間接依賴的模塊不需要改動
apicompile依賴項在編譯時對模塊可用,并且在編譯時和運行時還對模塊的消費者可用, 此配置的行為類似于 compile(現在已棄用),一般情況下,您應當僅在庫模塊中使用它, 應用模塊應使用 implementation,除非您想要將其 API 公開給單獨的測驗模塊,api 會暴露給間接依賴的模塊,使用此配置,在模塊修改以后,模塊的直接依賴和間接依賴的模塊都需要重新編譯
compileOnlyprovided依賴項僅在編譯時對模塊可用,并且在編譯或運行時對其消費者不可用, 此配置的行為類似于 provided(現在已棄用),只在編譯期間依賴模塊,打包以后運行時不會依賴,可以用來解決一些庫沖突的問題
runtimeOnlyapk依賴項僅在運行時對模塊及其消費者可用, 此配置的行為類似于 apk(現在已棄用),只在運行時依賴模塊,編譯時不依賴

現在假設專案里有三個模塊:app,module1, module2

  • 模塊 app 中有一個類 ModuleApi
  • 模塊 module1 中有一個類 Module1Api
  • 模塊 module2 中有一個類 Module2Api

其依賴關系如下:

1. implementation 依賴
當 module1 使用 implementation 依賴 module2 時,在 app 模塊中無法參考到 Module2Api 類,

2. api 依賴
當 module1 使用 api 依賴 module2 時,在 app 模塊中可以正常參考到 Module2Api 類,

3. compileOnly 依賴
當 module1 使用 compileOnly 依賴 module2 時,在編譯階段 app 模塊無法參考到 Module2Api 類,module1 中正常參考,但是在運行時會報錯,

反編譯打包好的 apk,可以看到 Module2Api 是沒有被打包到 apk 里的,

4. runtimeOnly 依賴
當 module1 使用 runtimeOnly 依賴 module2 時,在編譯階段,module1 也無法參考到 Module2Api,

五、Gradle Flavor

Flavor是在Gradle中配置多渠道的打包的工具,它將 debug 和 release 維度進一步擴大,

在 android gradle plugin 3.x 之后,每個 flavor 必須對應一個 dimension,可以理解為 flavor 的分組,然后不同 dimension 里的 flavor 兩兩組合形成一個 variant

flavorDimensions "size", "color"

productFlavors {
    big {
        dimension "size"
    }
    small {
        dimension "size"
    }
    blue {
        dimension "color"
    }
    red {
        dimension "color"
    }
}

那么生成的 variant 對應的就是 bigBlue,bigRed,smallBlue,smallRed,
每個 variant 可以對應的使用 variantImplementation 來引入特定的依賴,比如:bigBlueImplementation,只有在 編譯 bigBlue variant的時候才會引入,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/252165.html

標籤:其他

上一篇:HDU-2182 Forg 動態規劃DP 題解

下一篇:Gradle插件實戰之編譯期修改代碼

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more