Android Studio是採用gradle來構建項目的,gradle是基於groovy語言的,若是隻是用它構建普通Android項目的話,是能夠不去學groovy的。當咱們建立一個Android項目時會包含兩個Android build.gradle配置詳解文件,以下圖:javascript
對應的build.gradle代碼以下:php
// 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 {
classpath 'com.android.tools.build:gradle:3.0.0'////此處是android的插件gradle,gradle是一個強大的項目構建工具
// 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.buildDir)。
// gradle使用groovy語言,調用method時能夠不用加()。
task clean(type: Delete) {
delete rootProject.buildDir
}
複製代碼
該閉包中聲明瞭jcenter()和google()的配置,其中jcenter是一個代碼託管倉庫,上面託管了不少Android開源項目,在這裏配置了jcenter後咱們能夠在項目中方便引用jcenter上的開源項目,從Android Studio3.0後新增了google()配置,能夠引用google上的開源項目。java
該閉包使用classpath聲明瞭一個Gradle插件,因爲Gradle並不僅是用來構建Android項目,所以此處引入相關插件來構建Android項目,其中'3.0.0'爲該插件的版本號,能夠根據最新的版本號來調整。android
從文件內容能夠看出,主要分爲三大部分,以下圖所示:c++
// 聲明是Android程序,
//com.android.application 表示這是一個應用程序模塊
//com.android.library 標識這是一個庫模塊
//而這區別:前者能夠直接運行,後着是依附別的應用程序運行
apply plugin: 'com.android.application'
複製代碼
文件中第一行使用apply plugin表示應用了一個插件,該插件通常有兩種值可選:git
這個閉包主要爲了配置項目構建的各類屬性:github
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,點擊Singing添加,具體步驟以下圖所示:windows
簽名配置完成後能夠方便帶簽名打包,在module的Build Variants中有兩個Type,分別是debug和release,能夠選擇任意一個類型進行打包,而且他們會利用各自配置的Key進行打包,執行 Run app或者Build->Build apk就會自動在module name/app/build/outputs/apk路徑下生成Apk文件。另外一種打包方式是Build->Generate Signed APK填寫簽名信息生成Apk。api
compileSdkVersion 27//設置編譯時用的Android版本
defaultConfig {
applicationId "com.billy.myapplication"//項目的包名
minSdkVersion 16//項目最低兼容的版本
targetSdkVersion 27//項目的目標版本
versionCode 1//版本號
versionName "1.0"//版本名稱
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"//代表要使用AndroidJUnitRunner進行單元測試
}
複製代碼
這個閉包主要指定生成安裝文件的主要配置,通常包含兩個子閉包,一個是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 中添加了一個後綴,通常使用的很少
}
}
複製代碼
sourceSets {//目錄指向配置
main {
jniLibs.srcDirs = ['libs']//指定lib庫目錄
}
}
複製代碼
配置 jniLibs.srcDirs = ['libs'],能夠在Android studio的Android視圖下生成jniLibs文件夾,能夠方便咱們存放jar包和庫文件,其中Android視圖下的jniLibs和project視圖下的libs指向同一文件夾(app→libs),以下圖所示:
當項目中依賴的第三方庫愈來愈多時,有可能會出現兩個依賴庫中存在同一個(名稱)文件。若是這樣,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'
}
複製代碼
這個配置是常常會使用到的,一般在適配多個渠道的時候,須要爲特定的渠道作部分特殊的處理,好比設置不一樣的包名、應用名等。場景:當咱們使用友盟統計時,一般須要設置一個渠道ID,那麼咱們就能夠利用productFlavors來生成對應渠道信息的包,如:
android {
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 {
targetSdkVersion:***
minSdkVersion :***
versionCode:***
versionName :***
//版本名後面添加一句話,意思就是flavor dimension 它的維度就是該版本號,這樣維度就是都是統一的了
flavorDimensions "versionCode"
}
Lint 是Android Studio 提供的 代碼掃描分析工具,它能夠幫助咱們發現代碼結構/質量問題,同時提供一些解決方案,並且這個過程不須要咱們手寫測試用例。
Lint 發現的每一個問題都有描述信息和等級(和測試發現 bug 很類似),咱們能夠很方便地定位問題,同時按照嚴重程度進行解決。
//程序在編譯的時候會檢查lint,有任何錯誤提示會中止build,咱們能夠關閉這個開關
lintOptions {
abortOnError false //即便報錯也不會中止打包
checkReleaseBuilds false //打包release版本的時候進行檢測
}
複製代碼
該閉包定義了項目的依賴關係,通常項目都有三種依賴方式:本地依賴、庫依賴和遠程依賴。本地依賴能夠對本地的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'
}
複製代碼
// 聲明是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'
}
複製代碼