Android中的build.gradle文件深入講解
一、什么是Gradle
gradle是一個(gè)項(xiàng)目構(gòu)建工具,java開(kāi)發(fā)中有兩個(gè)大名鼎鼎的項(xiàng)目構(gòu)建Maven,Ant,其中maven簡(jiǎn)單易控深受開(kāi)發(fā)者喜愛(ài)。
項(xiàng)目構(gòu)建工具是什么?能干嗎?
開(kāi)發(fā)某些項(xiàng)目時(shí),需要很多jar或者庫(kù)的支持,還沒(méi)開(kāi)始開(kāi)發(fā)就下載了n多個(gè)庫(kù),浪費(fèi)了時(shí)間不說(shuō),這些庫(kù)之間兼容性又無(wú)法保證。刪了?白下載了。不刪?又不兼容。此時(shí)就需要使用項(xiàng)目構(gòu)建工具,簡(jiǎn)單的說(shuō)就是一個(gè)可以根據(jù)簡(jiǎn)單的配置文件自動(dòng)去下載相應(yīng)包/庫(kù)的軟件。自動(dòng)的還很簡(jiǎn)單,不用豈不虧了。多個(gè)項(xiàng)目構(gòu)建工具各有特點(diǎn),但是核心思想一樣。
簡(jiǎn)單的說(shuō),Gradle是一個(gè)構(gòu)建工具,它是用來(lái)幫助我們構(gòu)建app的,構(gòu)建包括編譯、打包等過(guò)程。我們可以為Gradle指定構(gòu)建規(guī)則,然后它就會(huì)根據(jù)我們的“命令”自動(dòng)為我們構(gòu)建app。Android Studio中默認(rèn)就使用Gradle來(lái)完成應(yīng)用的構(gòu)建。有些同學(xué)可能會(huì)有疑問(wèn):”我用AS不記得給Gradle指定過(guò)什么構(gòu)建規(guī)則呀,最后不還是能搞出來(lái)個(gè)apk?!?實(shí)際上,app的構(gòu)建過(guò)程是大同小異的,有一些過(guò)程是”通用“的,也就是每個(gè)app的構(gòu)建都要經(jīng)歷一些公共步驟。因此,在我們?cè)趧?chuàng)建工程時(shí),Android Studio自動(dòng)幫我們生成了一些通用構(gòu)建規(guī)則,很多時(shí)候我們甚至完全不用修改這些規(guī)則就能完成我們app的構(gòu)建。
有些時(shí)候,我們會(huì)有一些個(gè)性化的構(gòu)建需求,比如我們引入了第三方庫(kù),或者我們想要在通用構(gòu)建過(guò)程中做一些其他的事情,這時(shí)我們就要自己在系統(tǒng)默認(rèn)構(gòu)建規(guī)則上做一些修改。這時(shí)候我們就要自己向Gradle”下命令“了,這時(shí)候我們就需要用Gradle能聽(tīng)懂的話(huà)了,也就是Groovy。Groovy是一種基于JVM的動(dòng)態(tài)語(yǔ)言,關(guān)于它的具體介紹,感興趣的同學(xué)可以文末參考”延伸閱讀“部分給出的鏈接。
我們?cè)陂_(kāi)頭處提到“Gradle是一種構(gòu)建工具”。實(shí)際上,當(dāng)我們想要更靈活的構(gòu)建過(guò)程時(shí),Gradle就成為了一個(gè)編程框架——我們可以通過(guò)編程讓構(gòu)建過(guò)程按我們的意愿進(jìn)行。也就是說(shuō),當(dāng)我們把Gradle作為構(gòu)建工具使用時(shí),我們只需要掌握它的配置腳本的基本寫(xiě)法就OK了;而當(dāng)我們需要對(duì)構(gòu)建流程進(jìn)行高度定制時(shí),就務(wù)必要掌握Groovy等相關(guān)知識(shí)了。限于篇幅,本文只從構(gòu)建工具使用者的角度來(lái)介紹Gradle的一些最佳實(shí)踐,在文末“延伸閱讀”部分給出了幾篇高質(zhì)量的深入介紹Gradle的文章,其中包含了Groovy等知識(shí)的介紹。
二、Gradle的基本組分
1.Project和Task
在Gradle中,每一個(gè)待構(gòu)建的工程是一個(gè)Project,構(gòu)建一個(gè)Project需要執(zhí)行一系列Task,比如編譯、打包這些構(gòu)建過(guò)程的子過(guò)程都對(duì)應(yīng)著一個(gè)Task。具體來(lái)說(shuō),一個(gè)apk文件的構(gòu)建包含以下Task:Java源碼編譯、資源文件編譯、Lint檢查、打包以生成最終的apk文件等等。
2.插件
插件的核心工作有兩個(gè):一是定義Task;而是執(zhí)行Task。也就是說(shuō),我們想讓Gradle能正常工作,完成整個(gè)構(gòu)建流程中的一系列Task的執(zhí)行,必須導(dǎo)入合適的插件,這些插件中定義了構(gòu)建Project中的一系列Task,并且負(fù)責(zé)執(zhí)行相應(yīng)的Task。
在新建工程的app模塊的build.gradle文件的第一行,往往都是如下這句:
apply plugin: 'com.android.application'
這句話(huà)的意思就是應(yīng)用“com.android.application“這個(gè)插件來(lái)構(gòu)建app模塊,app模塊就是Gradle中的一個(gè)Project。也就是說(shuō),這個(gè)插件負(fù)責(zé)定義并執(zhí)行Java源碼編譯、資源文件編譯、打包等一系列Task。實(shí)際上"com.android.application"整個(gè)插件中定義了如下4個(gè)頂級(jí)任務(wù):
assemble: 構(gòu)建項(xiàng)目的輸出(apk)
check: 進(jìn)行校驗(yàn)工作
build: 執(zhí)行assemble任務(wù)與check任務(wù)
clean: 清除項(xiàng)目的輸出
當(dāng)我們執(zhí)行一個(gè)任務(wù)時(shí),會(huì)自動(dòng)執(zhí)行它所依賴(lài)的任務(wù)。比如,執(zhí)行assemble任務(wù)會(huì)執(zhí)行assembleDebug任務(wù)和assembleRelease任務(wù),這是因?yàn)橐粋€(gè)Android項(xiàng)目至少要有debug和release這兩個(gè)版本的輸出。
3.Gradle配置文件
我們?cè)贏ndroid Studio中新建一個(gè)工程,可以得到如下的工程結(jié)構(gòu)圖:
上面我們說(shuō)過(guò),Android Studio中的一個(gè)Module即為Gradle中的一個(gè)Project。上圖的app目錄下,存在一個(gè)build.gradle文件,代表了app Module的構(gòu)建腳本,它定義了應(yīng)用于本模塊的構(gòu)建規(guī)則。我們可以看到,工程根目錄下也存在一個(gè)build.gradle文件,它代表了整個(gè)工程的構(gòu)建,其中定義了適用于這個(gè)工程中所有模塊的構(gòu)建規(guī)則。
接下來(lái)我們介紹一下上圖中其他幾個(gè)Gradle配置文件:
gradle.properties: 從它的名字可以看出,這個(gè)文件中定義了一系列“屬性”。實(shí)際上,這個(gè)文件中定義了一系列供build.gradle使用的常量,比如keystore的存儲(chǔ)路徑、keyalias等等。
gradlew與gradlew.bat: gradlew為L(zhǎng)inux下的shell腳本,gradlew.bat是Windows下的批處理文件。gradlew是gradle wrapper的縮寫(xiě),也就是說(shuō)它對(duì)gradle的命令進(jìn)行了包裝,比如我們進(jìn)入到指定Module目錄并執(zhí)行“gradlew.bat assemble”即可完成對(duì)當(dāng)前Module的構(gòu)建(Windows系統(tǒng)下)。
local.properties: 從名字就可以看出來(lái),這個(gè)文件中定義了一些本地屬性,比如SDK的路徑。
settings.gradle: 假如我們的項(xiàng)目包含了不只一個(gè)Module時(shí),我們想要一次性構(gòu)建所有Module以完成整個(gè)項(xiàng)目的構(gòu)建,這時(shí)我們需要用到這個(gè)文件。比如我們的項(xiàng)目包含了ModuleA和ModuleB這兩個(gè)模塊,則這個(gè)文件中會(huì)包含這樣的語(yǔ)句:include ':ModuleA', ':ModuleB'。
4.構(gòu)建腳本
首先我們來(lái)看一下工程目錄下的build.gradle,它指定了真?zhèn)€整個(gè)項(xiàng)目的構(gòu)建規(guī)則,它的內(nèi)容如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { google() jcenter()//構(gòu)建腳本中所依賴(lài)的庫(kù)都在jcenter倉(cāng)庫(kù)下載 } dependencies { classpath 'com.android.tools.build:gradle:3.2.1'//指定了gradle插件的版本 // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter()//當(dāng)前項(xiàng)目所有模塊所依賴(lài)的庫(kù)都在jcenter倉(cāng)庫(kù)下載 } } task clean(type: Delete) { delete rootProject.buildDir }
我們?cè)賮?lái)簡(jiǎn)單介紹下app模塊的build.gradle的內(nèi)容:
apply plugin: 'com.android.application'//加載用于構(gòu)建Android項(xiàng)目的插件 android {//構(gòu)建Android項(xiàng)目使用的配置 compileSdkVersion 28 //指定編譯項(xiàng)目時(shí)使用的SDK版本 defaultConfig { applicationId "com.example.ssts.myapplication"http://包名 minSdkVersion 15//指定支持的最小SDK版本 targetSdkVersion 28//針對(duì)的目標(biāo)SDK版本 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes {//針對(duì)不同的構(gòu)建版本進(jìn)行一些設(shè)置 release {//對(duì)release版本進(jìn)行的設(shè)置 minifyEnabled false//是否開(kāi)啟混淆 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆文件的位置 } } } dependencies {//指定當(dāng)前模塊的依賴(lài) implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' }
三、常見(jiàn)配置
整個(gè)工程的build.gradle通常不需我們改動(dòng),這里我們介紹下一些對(duì)模塊目錄下build.gradle文件的常見(jiàn)配置。
1.依賴(lài)第三方庫(kù)
當(dāng)我們的項(xiàng)目中用到了了一些第三方庫(kù)時(shí),我們就需要進(jìn)行一些配置,以保證能正確導(dǎo)入相關(guān)依賴(lài)。設(shè)置方法很簡(jiǎn)單,比如我們?cè)赼pp模塊中中用到了Fresco,只需要在build.gradle文件中的dependencies塊添加如下語(yǔ)句:
dependencies { ... compile 'com.facebook.fresco:fresco:0.11.0' }
這樣一來(lái),Gradle會(huì)自動(dòng)從jcenter倉(cāng)庫(kù)下載我們所需的第三方庫(kù)并導(dǎo)入到項(xiàng)目中。
2.導(dǎo)入本地jar包
在使用第三方庫(kù)時(shí),除了像上面那樣從jcenter倉(cāng)庫(kù)下載,我們還可以導(dǎo)入本地的jar包。配置方法也很簡(jiǎn)單,只需要先把jar文件添加到app\libs目錄下,然后在相應(yīng)jar文件上單擊右鍵,選擇“Ad As Library”。然后在build.gradle的dependencies塊下添加如下語(yǔ)句:
compile files('libs/xxx.jar')
實(shí)際上我們可以看到,系統(tǒng)為我們創(chuàng)建的build.gradle中就已經(jīng)包含了如下語(yǔ)句:
compile fileTree(dir: 'libs', include: ['*.jar'])
這句話(huà)的意思是,將libs目錄下的所有jar包都導(dǎo)入。所以實(shí)際上我們只需要把jar包添加到libs目錄下并“Ad As Library"即可。
3.依賴(lài)其它模塊
假設(shè)我們的項(xiàng)目包含了多個(gè)模塊,并且app模塊依賴(lài)other模塊,那么我們只需app\build.gradle的denpendencies塊下添加如下語(yǔ)句:
compile project(':other')
4.構(gòu)建輸出為aar文件
通常我們構(gòu)建的輸出目標(biāo)都是apk文件,但如果我們的當(dāng)前項(xiàng)目時(shí)Android Library,我們的目標(biāo)輸出就是aar文件。要想達(dá)到這個(gè)目的也很容易,只需要把build.gradle的第一句改為如下:
apply plugin:'com.android.library'
這話(huà)表示我們使用的插件不再是構(gòu)建Android應(yīng)用的插件,而是構(gòu)建Android Library的插件,這個(gè)插件定義并執(zhí)行用于構(gòu)建Android Library的一系列Task。
5.自動(dòng)移除不再使用的資源
只需進(jìn)行如下配置:
android { ... } buildTypes { release { ... shrinkResources true ... } } }
6.忽略Lint錯(cuò)誤
在我們構(gòu)建Android項(xiàng)目的過(guò)程中,有時(shí)候會(huì)由于Lint錯(cuò)誤而終止。當(dāng)這些錯(cuò)誤來(lái)自第三方庫(kù)中時(shí),我們往往想要忽略這些錯(cuò)誤從而繼續(xù)構(gòu)建進(jìn)程。這時(shí)候,我們可以只需進(jìn)行如下配置:
android { ... } buildTypes { release { ... shrinkResources true ... } } }
7.集成簽名配置
在構(gòu)建release版本的Android項(xiàng)目時(shí),每次都手動(dòng)導(dǎo)入簽名文件,鍵入密碼、keyalias等信息十分麻煩。通過(guò)將簽名配置集成到構(gòu)建腳本中,我們就不必每次構(gòu)建發(fā)行版本時(shí)都手動(dòng)設(shè)置了。具體配置如下:
signingConfigs { myConfig { //將"xx"替換為自己的簽名文件信息 storeFile file("xx.jks") storePassword "xx" keyAlias "xx" keyPassword "xx" } } android { buildTypes { release { signingConfig signingConfigs.myConfig //在release塊中加入這行 ... } } ... }
真實(shí)開(kāi)發(fā)中,我們不應(yīng)該把密碼等信息直接寫(xiě)到build.gradle中,更好的做法是放在gradle.properties中設(shè)置:
RELEASE_STOREFILE=xxx.jks RELEASE_STORE_PASSWORD = xxx RELEASE_KEY_ALIAS=xxx RELEASE_KEY_PASSWORD=xxx
然后在build.gradle中直接引用即可:
signingConfigs { myConfig { storeFilefile(RELEASE_STOREFILE) storePassword RELEASE_STORE_PASSWORD keyAlias RELEASE_KEY_ALIAS keyPassword RELEASE_KEY_PASSWORD } }
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- spring boot使用sonarqube來(lái)檢查技術(shù)債務(wù)
- 使用Sonarqube掃描Javascript代碼的示例
- Android Studio Gradle插件版本與Gradle版本之間的對(duì)應(yīng)關(guān)系
- Spring Boot配置Thymeleaf(gradle)的簡(jiǎn)單使用
- Spring Boot使用Thymeleaf + Gradle構(gòu)建war到Tomcat
- 優(yōu)化Gradle提升Gradle編譯速度
- 關(guān)于gradle你應(yīng)該知道的一些小事
- Android gradle插件打印時(shí)間戳的方法詳解
- 給Android初學(xué)者的Gradle知識(shí)普及
- Gradle進(jìn)階使用結(jié)合Sonarqube進(jìn)行代碼審查的方法
相關(guān)文章
Android編程單元測(cè)試實(shí)例詳解(附源碼)
這篇文章主要介紹了Android編程單元測(cè)試,結(jié)合完整實(shí)例形式詳細(xì)分析了Android單元測(cè)試的具體步驟與相關(guān)技巧,并附帶完整實(shí)例代碼供讀者下載參考,需要的朋友可以參考下2015-11-11Android利用MPAndroidChart繪制曲線圖表的基礎(chǔ)教程
最近在項(xiàng)目中要用到曲線圖,于是在網(wǎng)上找了很多很多,有AChartengine,MPAndroidChart,helloChart等等,我還用過(guò)基于html5的jsChart來(lái)做過(guò),不過(guò)最終還是選擇了MPAndroidChart來(lái)做本文介紹了Android利用MPAndroidChart繪制曲線圖表的基礎(chǔ)教程,需要的朋友可以參考下。2018-03-03android自定義view實(shí)現(xiàn)推箱子小游戲
這篇文章主要為大家詳細(xì)介紹了android自定義view實(shí)現(xiàn)推箱子小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04Android HttpURLConnection.getResponseCode()錯(cuò)誤解決方法
在使用HttpURLConnection.getResponseCode()的時(shí)候直接報(bào)錯(cuò)是IOException錯(cuò)誤,一直想不明白,同一個(gè)程序我調(diào)用了兩次,結(jié)果有一個(gè)鏈接一直O(jiān)K,另一個(gè)卻一直報(bào)這個(gè)錯(cuò)誤2013-06-06如何判斷軟件程序是否聯(lián)網(wǎng) 聯(lián)網(wǎng)狀態(tài)提示信息Android實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了如何判斷軟件程序是否聯(lián)網(wǎng)的實(shí)現(xiàn)代碼,Android實(shí)現(xiàn)聯(lián)網(wǎng)狀態(tài)信息提示,感興趣的小伙伴們可以參考一下2016-05-05flutter 中監(jiān)聽(tīng)滑動(dòng)事件
這篇文章主要介紹了flutter 中監(jiān)聽(tīng)滑動(dòng)事件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11Android音視頻開(kāi)發(fā)之VideoView使用指南
VideoView組件內(nèi)部同樣是使用MediaPlayer+SurfaceView的形式控制MediaPlayer對(duì)視頻文件進(jìn)行播放,本文就來(lái)詳細(xì)講講它的使用方法,需要的可以參考一下2022-04-04Android自定義GestureDetector實(shí)現(xiàn)手勢(shì)ImageView
這篇文章主要為大家詳細(xì)介紹了Android自定義GestureDetector實(shí)現(xiàn)手勢(shì)ImageView的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03