Gradle打包工具入門

1、Gradle介紹
Gradle
是一種自動化構建語言,是一種 DSL
。目前是 Android
的預設構建工具,是一個程式設計框架
Gradle
是一個基於 Apache Ant
和 Apache Maven
概念的專案自動化構建開源工具。它使用一種基於 Groovy
的特定領域語言(DSL)來宣告專案設定,也增加了基於 Kotlin
語言的 kotlin-based DSL
,拋棄了基於 XML
的各種繁瑣配置
特點:
- 支援區域性構建和增量構建
- 對多工程的構建支援很出色,工程依賴是
gradle
的第一公民 - 是第一個構建整合工具,與
ant
、maven
、ivy
有良好的相容相關性 -
gradle
的整體設計是以作為一種語言為導向的,而非成為一個嚴格死板的框架 - 支援多方式依賴管理:包括從
maven
遠端倉庫、nexus
私服、ivy
倉庫以及本地檔案系統的jars
或者dirs
- 輕鬆遷移:
gradle
適用於任何結構的工程,你可以在同一個開發平臺平行構建原工程和gradle
工程。通常要求寫相關測試,以保證開發的外掛的相似性,這種遷移可以減少破壞性,儘可能的可靠。這也是重構的最佳實踐
2、Gradle配置分析
2.1 根目錄配置
- settings.gradle
在程式碼編譯時最先找到這個檔案
apply from: 'allconfig.gradle' include: 'app' // 包含的工程模組 if(buildType==1){ include ':mylibrary2' }else if(buildType==2){ include ':mylibrary' } //在這裡寫一個指令碼,讓編譯速度更快 rootProject.name = 'gradledemo' // 工程名
- build.gradle
// 根目錄的構建指令碼 buildscript { // 指定了倉庫 repositories { maven { // 加速地址要放在最上面,從上往下找 url 'http://maven.aliyun.com/nexus/content/groups/public/' } google() jcenter() } dependencies { // 配置外掛 // gradle 外掛版本 classpath "com.android.tools.build:gradle:4.0.1" } } allprojects { // 專案本身需要的依賴,配置所有的Module公共依賴 repositories { maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } google() jcenter() } } // 任務 task Clean(type: Delete) { delete rootProject.buildDir // 清理每次編譯生成的檔案 }
2.2 應用目錄配置
- build.gradle
// 配置當前Module的屬性 // 如果宣告的是com.android.library 表示是一個依賴庫 // 如果宣告的是com.android.plugin 表示是一個外掛 // 如果宣告的是com.android.application 表示是一個app apply plugin: 'com.android.application' // 類似引入包一樣,引入外部的gradle配置檔案 apply from: 'config.gradle' android { compileSdkVersion 30 buildToolsVersion "30.0.2" defaultConfig { applicationId "com.mn.gradledemo" minSdkVersion 16 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndridJunitRunner" } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' testImplementation 'junit:junit:4.12' androidtestInstrumentation 'androidx.test.ext:junit:1.1.2' androidtestInstrumentation 'androidx.test.espresso:espresso-core:3.3.0' } } // 只要聲明瞭一個任務,不用呼叫就會執行 task stringText{ // 使用def宣告關鍵字 def str1 = "shuanyinhao"; def str2 = 'danyinhan'; println("${str1}---${str2}") }
- config.gradle
// ext就表示額外的屬性宣告 ext{ server = "prod" dataSource = "0" }
3、Gradle基礎語法
3.1 常規語法
// list task list{ def list=[1,2,3,4,5,6] def weekList = ['one','two','three'] println(list[0]) println(weekList[0]) for(int i in 1..10){ println i } // 這裡的it就表示每一個元素, it是一個關鍵字,表示它自己 weekList.each { println it } } // map task map{ def map:['name':'jack','age':19] println map['name'] map.each { println "key:${it.key},value:${it.value}" } println(methodA(2,3)) // 5 } // 在gradle語法當中,定義一個方法 // 如果在沒有return的情況下,函式預設會返回最後一行非空的值 def methodA(int a,int b){ a+b } // 怎樣定義一個物件 task javaBeanTask{ Student student = new Student() student.name = "Lily" student.age = 19 println student.name + "---${student.age}" println student.getName() + "---${student.getAge()}" } class Student{ String name int age String getName(){ return name } void setName(String name){ this.name = name } int getAge(){ return age } void setAge(int age){ this.age = age } }
3.2 閉包和it關鍵字
Groovy
中的閉包是一個開放,匿名的程式碼塊,可以接受引數,返回值並賦值給變數
閉包,是一個程式碼塊,或可以理解成一個匿名函式,在外部方法呼叫時,可以將其作為方法的實參傳遞給方法的形參,並在方法內部回撥此匿名函式,且回撥此匿名函式時可以傳遞實參給到匿名函式的內部去接收,並執行此匿名函式
同時,此程式碼塊或匿名函式也可以賦值給一個變數,使其具有自執行的能力,且最後一行的執行語句作為匿名函式的返回
// 閉包,自定義閉包 def mEach(closure){ for(int i in 1..5){ closure(i) } } def mEachWithParams(closure){ def map = ['name':'groovy','age':10] map.each{ closure(it.key,it.value) } } // 呼叫閉包 task closureTask{ // 回撥一個引數的時候,it就是指這個引數,就能用it,多個就不行了 mEach({ println it // a->println a }) mEachWithParams{ m,n—>println "${m} is ${n}" } }
4、環境區分
主要目的是不需要修改程式碼就能區分測試環境和生產環境
例如有這樣的程式碼目錄(不同環境的配置檔案)
app/src/main/filters/debug/config.properties app/src/main/filters/release/config.properties
通過讀取檔案流實現按不同環境區分
- build.gradle
// 配置當前Module的屬性 // 如果宣告的是com.android.library 表示是一個依賴庫 // 如果宣告的是com.android.plugin 表示是一個外掛 // 如果宣告的是com.android.application 表示是一個app apply plugin: 'com.android.application' // 類似引入包一樣,引入外部的gradle配置檔案 apply from: 'config.gradle' android { ... // 構建型別 buildTypes{ // 測試環境 debug{ // 引數: 宣告的型別、名字、屬性值 buildConfigField 'String','SERVER2',getServer2('debug') } release{ buildConfigField 'String','SERVER2',getServer2('release') } } } // 讀取檔案流,str代表debug還是release def getServer2(String str){ def SERVER2 Properties properties = new Properties(); // 相對路徑 def proFile = file("src/main/filters/"+str+"/config.properties") if(proFile.canRead()){ properties.load(new FileInputStream(proFile)) if(properties!=null){ SERVER2 = properties['SERVER2'] } } return SERVER2 }
5、多渠道打包
多渠道打包常用於安卓 app
,例如統計不同渠道的資料(投放到多個應用市場)
5.1 核心邏輯
主要核心實現如下
apply plugin: 'com.android.application' apply from: 'config.gradle' android { compileSdkVersion 30 buildToolsVersion "30.0.2" defaultConfig { applicationId "com.mn.gradledemo" minSdkVersion 16 targetSdkVersion 30 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndridJunitRunner" // 多渠道打包 flavorDimensions "versionCode" } ... // 構建型別 buildTypes{ // 測試環境 debug{ // 引數: 宣告的型別、名字、屬性值 buildConfigField 'String','SERVER2',getServer2('debug') android.applicationVariants.all{ variant -> variant.outputs.all{ def fileName = "${getCurrentTime()}_V{defaultConfig.versionName}_debug.apk" outputFileName = fileName } } } release{ buildConfigField 'String','SERVER2',getServer2('release') } } // 多渠道打包 productFlavors{ xiaomi{ buildConfigField 'String','PLATE_FORM',"\"xiaomi\"" manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"] } yinyongbao{ buildConfigField 'String','PLATE_FORM',"\"yingyongbao\"" manifestPlaceholders = [UMENG_CHANNEL_VALUE: "yingyongbao"] } } } static def getCurrentTime(){ return new Date().format("yyyy-MM-dd",timeZone.getTimeZone("UTC")) }
5.2 一鍵化配置多渠道打包
// 一鍵化多渠道打包 productFlavors{ xiaomi{} yingyongbao{} } productFlavors.all{ flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] buildConfigField 'String','PLATE_FORM',"\"${name}\"" }
6、gradle打包加速
和 maven
打包一樣, gradle
會在編譯時的使用者家目錄,例如 /root/.gradle
目錄下生成一個快取目錄,除此之外,在應用的目錄下也會生成一個 build
目錄,這個目錄下也有相應的 build cache
可以在全域性配置 gradle
,使其拉取外掛時走國內的源
配置檔案為 /root/.gradle/init.gradle
,內容如下
allprojects { repositories { mavenLocal() maven { name "Aliyun" ; url "https://maven.aliyun.com/repository/public" } maven { name "Bstek" ; url "http://nexus.bsdn.org/content/groups/public/" } } buildscript { repositories { maven { name "Aliyun" ; url 'https://maven.aliyun.com/repository/public' } maven { name "Bstek" ; url 'http://nexus.bsdn.org/content/groups/public/' } maven { name "M2" ; url 'https://plugins.gradle.org/m2/' } } } }
「其他文章」
- Gradle打包工具入門
- 服務網格和Istio初識-續
- 服務網格和Istio初識
- Golang與非對稱加密
- ack叢集Terway網路場景下的vSwitch擴容
- Golang與對稱加密
- 基於ack k8s叢集排程的方案設計
- 基於Dockerfile構建容器映象的最佳實踐
- Golang反射-下篇
- Golang反射-上篇
- Azure DevOps的使用入門
- Golang介面型別-下篇
- Golang介面型別-上篇
- 基於Python實現原生的登入驗證碼
- Golang開發命令列工具之flag包的使用
- Golang檔案操作-下篇
- k8s環境下處理容器時間問題的多種姿勢
- Golang基準測試
- 淺談Prometheus的資料儲存
- Golang單元測試