1.gradle是什么?
Gradle是新一代的自動化構建工具,一個基于JVM的構建工具,它是一個獨立的專案,跟AS,Android無關,類似Ant,Maven這類構建工具都是基于xml來進行描述的,很臃腫,而Gradle采用的是一種叫做Groovy的語言,語法跟Java語法很像,但是一種動態語言,而且在Java基礎上做了不少改進,用起來更加簡潔、靈活,而且Gradle完全兼容Maven、lvy,這點基本上宣布Maven、lvy可以被拋棄了,Gradle的推出主要以Java應用為主,當然目前還支持Android、C、C++;
構建工具就是對你的專案進行編譯、運行、簽名、打包、依賴管理等一系列功能集合,傳統的構建工具有Make、Ant、Maven、lvy等,而Gradle是新一代的自動化構建工具;
gradle優勢(gradle提供了什么)
1). 一種可切換的,像maven一樣的基于約定的構建框架,卻又從不鎖住你(約定優于配置)
2). 強大的支持多工程的構建
3). 強大的依賴管理(基于Apache Ivy),提供最大的便利去構建你的工程
4). 全力支持已有的Maven或者Ivy倉庫基礎建設
5). 支持傳遞性依賴管理,在不需要遠程倉庫和pom.xml和ivy組態檔的前提下
6). 基于groovy腳本構建,其build腳本使用groovy語言撰寫
7). 具有廣泛的領域模型支持你的構建
參考:gradle_百度百科
2.gradle如何參考?
Gradle 跟 Android Studio 其實沒有關系,但是 Gradle 官方還是很看重 Android 開發的,Google 在推出 AS 的時候選中了 Gradle 作為構建工具,為了支持 Gradle 能在 AS 上使用,Google 做了個 AS 的插件叫 Android Gradle Plugin ,所以我們能在 AS 上使用 Gradle 完全是因為這個插件的原因,在專案的根目錄有個 build.gradle 檔案,里面有這么一句代碼:
buildscript {
dependencies {
classpath "com.android.tools.build:gradle:4.1.2"
}
}
這個就是依賴 gradle 插件的代碼,后面的版本號代表的是 android gradle plugin 的版本,而不是 Gradle 的版本,這個是 Google 定的,跟 Gradle 官方沒關系,

Android Gradle Plugin每個版本的具體變化和具體功能參考:Android Gradle 插件版本說明 | Android 開發者 | Android Developers
3.gradle、android gradle plugin、gradle wrapper區別和聯系
- Gradle是個構建系統,可以簡化你的編譯、打包、測驗程序,熟悉Java的同窗,能夠把Gradle類比成Maven,
- Gradle Wrapper的做用是簡化Gradle自己的安裝、部署,現在默認新建一個專案,然后點擊 AS 上的運行,默認就會直接幫你安裝 Gradle ,我們不需要額外的安裝 Gradle 了,但是其實這個 Gradle 不是真正的 Gradle ,他叫 Gradle Wrapper ,意為 Gradle 的包裝,什么意思呢?假設我們本地有多個專案,一個是比較老的專案,還用著 Gradle 1.0 的版本,一個是比較新的專案用了 Gradle 2.0 的版本,但是你兩個專案肯定都想要同時運行的,如果你只裝了 Gradle 1.0 的話那肯定不行,所以為了解決這個問題,Google 推出了 Gradle Wrapper 的概念,就是他在你每個專案都配置了一個指定版本的 Gradle ,你可以理解為每個 Android 專案本地都有一個小型的 Gradle ,通過這個每個專案你可以支持用不同的 Gradle 版本來構建專案,
- Android Plugin for Gradle是一堆適合Android開發的Gradle插件的集合,主要由Google的Android團隊開發,Gradle不是Android的專屬構建系統,可是有了Android Plugin for Gradle的話,你會發現使用Gradle構建Android專案尤為的簡單,
4.Android工程gradle配置?
4.1.Android下多模塊gradle配置目錄結構
project
├─── setting.gradle
├─── build.grade
├─── app
│ └─── build.gradle
└─── libraries
├─── library1
│ └─── build.gradle
└─── library2
└─── build.gradle
以一個測驗專案為例,來介紹下一個完整的Android專案包含的基本Gradle相關的配置:

紅色標記部分從上到下一步步分析;
4.1.1.FlotWindow/app/build.gradle
這個檔案是app檔案夾下這個Module的gradle組態檔,也可以算是整個專案最主要的gradle組態檔,具體里面的配置下面會介紹;
每個Module都需要有一個gradle組態檔,語法都是一樣,唯一不同的是開頭可能不一樣;
可以獨立為APP的Module使用開頭:
plugins {
id 'com.android.application'
}
作為library的Module使用開頭:
plugins {
id 'com.android.library'
}
4.1.2FloatWindow/gradle
這個目錄下有個wrapper檔案夾,里面可以看到兩個檔案,我們主要看下gradle-wrapper.properties這個檔案的內容:
#Thu Nov 04 13:56:00 CST 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
其中GRADLE_USER_HOME通常指~/.gradle,從圖示專案中能夠知道我要使用gradle-6.5版本,從https://services.gradle.org/distributions/gradle-6.5-bin.zip下載,下載到本地的~/.gradle/wrapper/dists目錄,那是否是各個專案的Gradle都要經過Gradle Wrapper下載,能不能全部的專案共用一個Gradle?這樣理論上是能夠的,可是因為Gradle自己不必定保持徹底的兼容性,因此新老專案共用一個Gradle有時可能會遇到意想不到的問題,指定對應版本的Gradle,而不經過Gradle Wrapper下載的設定方式是選擇Specified location同時指定Gradle home:

4.1.3FloatWindow/build.gradle
這個檔案是整個專案的gradle基礎組態檔,默認的內容就是宣告了android gradle plugin的版本;
buildscript {
dependencies {
classpath "com.android.tools.build:gradle:4.1.2"
}
}
4.1.4FloatWindow/setting.gradle
這個檔案是全域專案組態檔,里面主要生命一些需要加入gradle的module,我們看看FloatWindow內容:
include ':app' include ':library' rootProject.name = "FloatWindowL"
5.Android工程下全域build.gradle配置和Module下build.gradle配置說明?
5.1Project全域build.gradle配置
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {//這里是gradle腳本執行所需依賴,分別對應的maven庫和插件
repositories {
google()//Android Studio3.0后新增了google()配置,可以參考google上的開源專案
jcenter()//是一個類似于github的代碼托管倉庫,宣告了jcenter()配置,可以輕松參考 jcenter上的開源專案
}
dependencies {
//此處是android的插件gradle,gradle是一個強大的專案構建工具
classpath "com.android.tools.build:gradle:4.1.2"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects { //這里是專案本身需要的依賴,比如專案所需的maven庫
repositories {
google()
jcenter()
}
}
//運行gradle clean時,執行此處定義的task任務;
//該任務繼承自Delete,洗掉根目錄中的build目錄
//相當于執行Delete.delete(rootProject.bulidDir)
//gradle使用groovy語言,呼叫method時可以不用加(),
task clean(type: Delete) {
delete rootProject.buildDir
}
- buildscript{}閉包里是gradle腳本執行所需依賴,分別是對應的maven庫和插件;
- allprojects{}閉包里是專案本身需要的依賴,比如專案所需要的maven庫;
- task clean(type: Delete){}是運行gradle clean時,執行此處定義的task任務,該任務繼承自Delete,洗掉根目錄中的build目錄;其中buildscript包含repositories閉包和dependencies閉包;
repositories{}閉包:配置遠程倉庫
該閉包中宣告了jcenter()和google()的配置,其中jcenter是一個代碼托管倉庫,上面托管了很多Android開源專案,在這里配置了jcenter后我們可以在專案中方便參考jcenter上的開源專案,從Android Studio3.0后新增了google()配置,可以參考google上的開源專案;
dependencies{}閉包:配置構造工具
該閉包使用classpath宣告了一個gradle插件,由于gradle并不是用來構建Android專案,因此此處引入相關插件來構建Android專案,啟動4.1.2為該插件的版本號,可以根據最新的版本號調整;
5.2Module下build.gradle配置
從檔案內容可以看出,主要分為三部分,如下:
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.gome.floatwindowl"
minSdkVersion 17
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.navigation:navigation-fragment:2.2.2'
implementation 'androidx.navigation:navigation-ui:2.2.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
5.2.1plugin
//宣告Android程式
//com.android.application 表示這是一個應用程式模塊
//com.android.library 標識這是一個庫模塊
//區別:前者可以直接運行,后者是依附別的應用程式運行
plugins {
id 'com.android.application'
}
檔案中第一行使用plugin表示應用一個插件,該插件一般有兩種值選擇:
- com.android.application,表示該模塊為應用程式模塊,可以直接運行,打包得到的是.apk檔案
- com.android.library,表示該模塊為庫模塊,只能作為代碼庫依附于別的應用程式模塊來運行,打包得到的是.aar檔案
5.2.2android{}閉包
這個閉包主要為了配置專案構建的各種屬性;
添加signingConfigs{}閉包:
signingConfigs {// 自動化打包配置
release {// 線上環境
keyAlias 'test'
keyPassword '123456'
storeFile file('test.keystore')
storePassword '123456'
}
debug {// 開發環境
keyAlias 'test'
keyPassword '123456'
storeFile file('test.keystore')
storePassword '123456'
}
}
可以手動添加簽名配置,也可以通過Project Structure選中app,點擊Signing添加,具體步驟如下圖所示:

簽名配置完成后可以方便帶簽名打包,在module的Build Variants中有兩個Type,分別是debug和release,可以選擇任意一個型別進行打包,并且他們會利用各自配置的Key進行打包,執行 Run app或者Build->Build apk就會自動在module name/app/build/outputs/apk路徑下生成Apk檔案,另一種打包方式是Build->Generate Signed APK填寫簽名資訊生成Apk,
compileSdkVersion:設定編譯時用的Android版本;
buildToolsVersion:設定編譯時使用的構建工具版本,Android Studio3.0后去除此項配置;
defaultConfig{}閉包:
compileSdkVersion 30 //設定專案編譯時用的Android版本
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.gome.floatwindowl" //專案包名
minSdkVersion 17 //專案最低的兼容版本
targetSdkVersion 30 //專案的目標版本
versionCode 1 //版本號
versionName "1.0" //版本名稱
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" //表明要使用AndroidJUnitRunner進行單元測驗
}
- applicationId:指定了專案的包名,
- minSdkVersion:指定專案最低兼容的版本,如果設備小于這個版本或者大于maxSdkVersion(一般不用)將無法安裝這個應用,這里指定為16,表示最低兼容到Android 4.1系統,
- targetSdkVersion:指定專案的目標版本,表示在該目標版本上已經做過充分測驗,系統會為該應用啟動一些對應該目標系統的最新功能特性,Android系統平臺的行為變更,只有targetSdkVersion的屬性值被設定為大于或等于該系統平臺的API版本時,才會生效,例如,若指定targetSdkVersion值為22,則表示該程式最高只在Android5.1版本上做過充分測驗,在Android6.0系統上(對應targetSdkVersion為23)擁有的新特性如系統運行時權限等功能就不會被啟用,
- versionCode:表示版本號,一般每次打包上線時該值只能增加,打包后看不見,
- versionName:表示版本名稱,展示在應用市場上,
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"表明要使用AndroidJUnitRunner進行單元測驗,
buildTypes{}閉包:
這個閉包主要指定生成安裝檔案的主要配置,一般包含兩個子閉包,一個是debug閉包,用于指定生成測驗版安裝檔案的配置,可以忽略不寫;另一個是release閉包,用于指定生成正式版安裝檔案的配置,兩者能配置的引數相同,最大的區別默認屬性配置不一樣,兩種模式支持的屬性配置如下圖:

buildTypes {// 生產/測驗環境配置
release {// 生產環境
buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前綴
minifyEnabled false//是否對代碼進行混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則檔案
signingConfig signingConfigs.release//設定簽名資訊
pseudoLocalesEnabled false//是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多
zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率
applicationIdSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
versionNameSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
}
debug {// 測驗環境
buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前綴
minifyEnabled false//是否對代碼進行混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則檔案
signingConfig signingConfigs.debug//設定簽名資訊
debuggable false//是否支持斷點除錯
jniDebuggable false//是否可以除錯NDK代碼
renderscriptDebuggable false//是否開啟渲染腳本就是一些c寫的渲染方法
zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率
pseudoLocalesEnabled false//是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多
applicationIdSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
versionNameSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
}
}
release{}閉包和debug{}閉包兩者能配置的引數相同,最大的區別默認屬性配置不一樣:
- minifyEnabled:表明是否對代碼進行混淆,true表示對代碼進行混淆,false表示對代碼不進行混淆,默認的是false,
- proguardFiles:指定混淆的規則檔案,這里指定了proguard-android.txt檔案和proguard-rules.pro檔案兩個檔案,proguard-android.txt檔案為默認的混淆檔案,里面定義了一些通用的混淆規則,proguard-rules.pro檔案位于當前專案的根目錄下,可以在該檔案中定義一些專案特有的混淆規則,
- buildConfigField:用于解決Beta版本服務和Release版本服務地址不同或者一些Log列印需求控制的,例如:配置buildConfigField(“boolean”, “LOG_DEBUG”, “true”),這個方法接收三個非空的引數,第一個:確定值的型別,第二個:指定key的名字,第三個:傳值,呼叫的時候BuildConfig.LOG_DEBUG即可呼叫,
- debuggable:表示是否支持斷點除錯,release默認為false,debug默認為true,
- jniDebuggable:表示是否可以除錯NDK代碼,使用lldb進行c和c++代碼除錯,release默認為false
- signingConfig:設定簽名資訊,通過signingConfigs.release或者signingConfigs.debug,配置相應的簽名,但是添加此配置前必須先添加signingConfigs閉包,添加相應的簽名資訊,
- renderscriptDebuggable:表示是否開啟渲染腳本就是一些c寫的渲染方法,默認為false,
- renderscriptOptimLevel:表示渲染等級,默認是3,
- pseudoLocalesEnabled:是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多,
- applicationIdSuffix:和defaultConfig中配置是一的,這里是在applicationId 中添加了一個后綴,一般使用的不多,
- versionNameSuffix:表示添加版本名稱的后綴,一般使用的不多,
- zipAlignEnabled:表示是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率,release和debug默認都為true,
sourceSets{}閉包:配置目錄指向
sourceSets {//目錄指向配置
main {
jniLibs.srcDirs = ['libs']//指定lib庫目錄
}
}
配置 jniLibs.srcDirs = [‘libs’],可以在Android studio的Android視圖下生成jniLibs檔案夾,可以方便我們存放jar包和庫檔案,其中Android視圖下的jniLibs和project視圖下的libs指向同一檔案夾(app→libs),如下圖所示:

當需要除錯版本和正式版本使用不同的manifest檔案時,可以做如下配置:
sourceSets {
main {
if (isDebug.toBoolean()) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/release/AndroidManifest.xml'
}
}
}
packagingOptions{}閉包:打包時的相關配置
當專案中依賴的第三方庫越來越多時,有可能會出現兩個依賴庫中存在同一個(名稱)檔案,如果這樣,Gradle在打包時就會提示錯誤(警告),那么就可以根據提示,然后使用以下方法將重復的檔案剔除,比較常用的是通過exclude去除重復的檔案,例如:
packagingOptions{
//pickFirsts做用是 當有重復檔案時 打包會報錯 這樣配置會使用第一個匹配的檔案打包進入apk
// 表示當apk中有重復的META-INF目錄下有重復的LICENSE檔案時 只用第一個 這樣打包就不會報錯
pickFirsts = ['META-INF/LICENSE']
//merges何必 當出現重復檔案時 合并重復的檔案 然后打包入apk
//這個是有默認值得 merges = [] 這樣會把默默認值去掉 所以我們用下面這種方式 在默認值后添加
merge 'META-INF/LICENSE'
//這個是在同時使用butterknife、dagger2做的一個處理,同理,遇到類似的問題,只要根據gradle的提示,做類似處理即可,
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
productFlavors{}閉包:多個渠道配置
這個配置是經常會使用到的,通常在適配多個渠道的時候,需要為特定的渠道做部分特殊的處理,比如設定不同的包名、應用名等,場景:當我們使用友盟統計時,通常需要設定一個渠道ID,那么我們就可以利用productFlavors來生成對應渠道資訊的包,如:
productFlavors {
wandoujia {
//豌豆莢渠道包配置
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
//manifestPlaceholders的使用在后續章節(AndroidManifest里的占位符)中介紹
}
xiaomi {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
applicationId "com.wiky.gradle.xiaomi" //配置包名
}
_360 {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
}
//...
}
當然也有更簡潔的方式
android {
productFlavors {
wandoujia {}
xiaomi {}
_360 {}
//...
}
productFlavors.all {
//批量修改,類似一個循序遍歷
flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}
}
配置完之后,在命令列視窗中(Terminal)中輸入gradlew assembleRelease(windows)即可開始打包,在Mac系統中對應指令應該是./gradlew assembleRelease,當然,如果想要debug版本的包,將指令中assembleRelease改為assembleDebug即可,最后生成的包還是在
app/build/outputs/apk中,默認命名格式如app-wandoujia-release-unsigned.apk,在module的Build Variants中可以選擇相應的渠道,
注:Android Studio3.0需在主app的build.gradle里面的
defaultConfig {applicationId:"xxx.xxx.xxx"
targetSdkVersion:***
minSdkVersion :***
versionCode:***
versionName :***
//版本名后面添加一句話,意思就是flavor dimension 它的維度就是該版本號,這樣維度就是都是統一的了
flavorDimensions “versionCode”
}
lintOptions{}閉包:代碼掃描分析
Lint 是Android Studio 提供的 代碼掃描分析工具,它可以幫助我們發現代碼結構/質量問題,同時提供一些解決方案,而且這個程序不需要我們手寫測驗用例,
Lint 發現的每個問題都有描述資訊和等級(和測驗發現 bug 很相似),我們可以很方便地定位問題,同時按照嚴重程度進行解決,
//程式在編譯的時候會檢查lint,有任何錯誤提示會停止build,我們可以關閉這個開關
lintOptions {
abortOnError false //即使報錯也不會停止打包
checkReleaseBuilds false //打包release版本的時候進行檢測
}
5.2.3dependencies{}閉包
該閉包定義了專案的依賴關系,一般專案都有三種依賴方式:本地依賴、庫依賴和遠程依賴,本地依賴可以對本地的jar包或目錄添加依賴關系,庫依賴可以對專案中的庫模塊添加依賴關系,遠程依賴可以對jcener庫上的開源專案添加依賴關系,從Android Studio3.0后compile引入庫不在使用,而是通過api和implementation,api完全等同于以前的compile,用api引入的庫整個專案都可以使用,用implementation引入的庫只有對應的Module能使用,其他Module不能使用,由于之前的專案統一用compile依賴,導致的情況就是模塊耦合性太高,不利于專案拆解,使用implementation之后雖然使用起來復雜了但是做到降低偶合興提高安全性,
dependencies {//專案的依賴關系
implementation fileTree(include: ['*.jar'], dir: 'libs')//本地jar包依賴
implementation 'com.android.support:appcompat-v7:27.1.1'//遠程依賴
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
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'
}
- implementation fileTree(include: [’*.jar’], dir: ‘libs’):implementation fileTree是一個本地依賴宣告,表示將libs目錄下所有.jar后綴的檔案都添加到專案的構建路徑當中,
- implementation ‘com.android.support:appcompat-v7:27.1.1’:implementation陳述句為 遠程依賴宣告,'com.android.support:appcompat-v7:27.1.1’為一個標準的遠程依賴庫格式,其中com.android.support為域名部分,用于區分不同公司的庫;appcompat-v7為組件名稱,用于區分同一個公司的不同庫;27.1.1為版本號,用于區分同一個庫的不同版本,加上這句宣告后,Gradle在構建專案時會先檢查一下本地是否已經快取過該庫,若沒有快取則自動聯網下載,下載后自動添加到專案的構建路徑中去,
- testImplementation和androidTestImplementation:表示宣告測驗用例庫,
5.3Module完整的build.gradle配置
// 宣告是Android程式,
//com.android.application 表示這是一個應用程式模塊
//com.android.library 標識這是一個庫模塊
//而這區別:前者可以直接運行,后著是依附別的應用程式運行
apply plugin: 'com.android.application'
android {
signingConfigs {// 自動化打包配置
release {// 線上環境
keyAlias 'test'
keyPassword '123456'
storeFile file('test.jks')
storePassword '123456'
}
debug {// 開發環境
keyAlias 'test'
keyPassword '123456'
storeFile file('test.jks')
storePassword '123456'
}
}
compileSdkVersion 27//設定編譯時用的Android版本
defaultConfig {
applicationId "com.billy.myapplication"//專案的包名
minSdkVersion 16//專案最低兼容的版本
targetSdkVersion 27//專案的目標版本
versionCode 1//版本號
versionName "1.0"//版本名稱
flavorDimensions "versionCode"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//表明要使用AndroidJUnitRunner進行單元測驗
}
buildTypes {// 生產/測驗環境配置
release {// 生產環境
buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
buildConfigField("String", "URL_PERFIX", "\"https://release.cn/\"")// 配置URL前綴
minifyEnabled false//是否對代碼進行混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則檔案
signingConfig signingConfigs.release//設定簽名資訊
pseudoLocalesEnabled false//是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多
zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率
applicationIdSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
versionNameSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
}
debug {// 測驗環境
buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
buildConfigField("String", "URL_PERFIX", "\"https://test.com/\"")// 配置URL前綴
minifyEnabled false//是否對代碼進行混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的規則檔案
signingConfig signingConfigs.debug//設定簽名資訊
debuggable false//是否支持斷點除錯
jniDebuggable false//是否可以除錯NDK代碼
renderscriptDebuggable false//是否開啟渲染腳本就是一些c寫的渲染方法
zipAlignEnabled true//是否對APK包執行ZIP對齊優化,減小zip體積,增加運行效率
pseudoLocalesEnabled false//是否在APK中生成偽語言環境,幫助國際化的東西,一般使用的不多
applicationIdSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
versionNameSuffix 'test'//在applicationId 中添加了一個后綴,一般使用的不多
}
}
sourceSets {//目錄指向配置
main {
jniLibs.srcDirs = ['libs']//指定lib庫目錄
}
}
packagingOptions{//打包時的相關配置
//pickFirsts做用是 當有重復檔案時 打包會報錯 這樣配置會使用第一個匹配的檔案打包進入apk
// 表示當apk中有重復的META-INF目錄下有重復的LICENSE檔案時 只用第一個 這樣打包就不會報錯
pickFirsts = ['META-INF/LICENSE']
//merges何必 當出現重復檔案時 合并重復的檔案 然后打包入apk
//這個是有默認值得 merges = [] 這樣會把默默認值去掉 所以我們用下面這種方式 在默認值后添加
merge 'META-INF/LICENSE'
//這個是在同時使用butterknife、dagger2做的一個處理,同理,遇到類似的問題,只要根據gradle的提示,做類似處理即可,
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
productFlavors {
wandoujia {}
xiaomi {}
_360 {}
}
productFlavors.all {
//批量修改,類似一個循序遍歷
flavor -> flavor.manifestPlaceholders = [IFLYTEK_CHANNEL: name]
}
//程式在編譯的時候會檢查lint,有任何錯誤提示會停止build,我們可以關閉這個開關
lintOptions {
abortOnError false
//即使報錯也不會停止打包
checkReleaseBuilds false
//打包release版本的時候進行檢測
}
}
dependencies {
//專案的依賴關系
implementation fileTree(include: ['*.jar'], dir: 'libs')
//本地jar包依賴
implementation 'com.android.support:appcompat-v7:27.1.1'
//遠程依賴
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
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'
}
6.Android的APK編譯流程
APK的構建程序可以根據官方提供的流程圖如下圖所示

這個APK構建的程序主要分為以下幾步:
1. 通過AAPT(Android Asset Packaging Tool)打包res資源檔案,比如AndroidManifest.xml、xml布局檔案等,并將這些xml檔案編譯為二進制,其中assets和raw檔案夾的檔案不會被編譯為二進制,最侄訓生成R.java和resources.arsc檔案,
2. AIDL工具會將所有的aidl介面轉化為對應的Java介面,
3. 所有的Java代碼,包括R.java和Java介面都會被Java編譯器編譯成.class檔案,
4. Dex工具會將上一步生成的.class檔案、第三庫和其他.class檔案編譯成.dex檔案,
5. 上一步編譯生成的.dex檔案、編譯過的資源、無需編譯的資源(如圖片等)會被ApkBuilder工具打包成APK檔案,
6. 使用Debug Keystore或者Release Keystore對上一步生成的APK檔案進行簽名,
7. 如果是對APK正式簽名,還需要使用zipalign工具對APK進行對齊操作,這樣應用運行時會減少記憶體的開銷,
從以上步驟可以看出,APK的構建程序是比較繁瑣的,而且這個構建程序又是時常重復的,如果沒有構建工具,手動去完成構建作業,無疑對于開發人員是個折磨,也會產生諸多的問題,導致專案開發周期變長,
7.認識下幾個命令
上面提到了,假設我們沒有 IDE ,只有類似 Sublime、Atom、Vim這種輕量編輯器怎么辦?那我們就沒法開發 Android 了么?然而只要有構建工具,不需要 IDE 我們一樣有辦法開發,這個時候我們就需要用到幾個有用的 Gradle 命令了:
./gradlew -v 版本號
./gradlew clean 清除9GAG/app目錄下的build檔案夾
./gradlew build 檢查依賴并編譯打包
這里注意的是 ./gradlew build 命令把 debug、release 環境的包都打出來,如果正式發布只需要打 Release 的包,該怎么辦呢,下面介紹一個很有用的命令 assemble , 如
./gradlew assembleDebug 編譯并打Debug包
./gradlew assembleRelease 編譯并打Release的包
值得注意的是,以上所有命令都是在終端里執行,并且必須要切換到所在專案的根目錄下執行,win系統直接執行 gradlew ,
參考:
史上最全Android build.gradle配置詳解_林偉茂的博客-CSDN博客
Android SourceSet 使用 參考 示例_TDC的專欄-CSDN博客
給 Android 初學者的 Gradle 知識普及 - 知乎
Android Gradle是什么?_xuwei_net的專欄-CSDN博客_android gradle
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/357149.html
標籤:其他
上一篇:iOS——FMDB的簡單使用
