目錄
1、前言
2、buildTypes
3、buildType
一、buildTypes存在形式
二、buildTypes 中屬性的意義
三、buildTypes 中方法的意義
4、寫在最後
html
繼 上一篇博客 分享了defaultConfig 中可配置參數的含義,今天咱們來分享另外一個咱們也很熟悉的 buildTypes
。java
buildTypes
也是存在於每一個應用級模塊中的 android 下的,即以下所示,是每次構建完項目以後自動生成的結構。android
android {
buildTypes{
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
複製代碼
buildTypes 能夠配置咱們須要的構建類型,例如咱們經常使用到的 「測試類型」 和 「本地類型」,則可使用以下配置git
buildTypes{
// 發佈類型
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
// 測試類型,給測試人員
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
// 本地類型,和後端聯調使用
local {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
複製代碼
增長完這些配置後,咱們能夠在 android studio 看到多了 「debug」 和 「local」 兩個能夠構建的類型,在 「點擊運行」 時,便會使用咱們所選擇的構建類型。假設此時選擇的是 「debug」 類型,咱們此時運行代碼,則是 debug 下的配置參數。 github
而這裏所說的 「release」,「debug」,「local」,三個構建類型其實即是三個 buildType
,buildType
所能配置的參數即是咱們今天要來捋清楚的。windows
buildType 官方文檔傳送門後端
從上一篇博客咱們知道,每一個配置最終會被映射爲一個類,或是一個屬性、或一個方法。buildType
也不例外,他會被映射爲 com.android.build.gradle.internal.dsl.BuildType
,繼承結構以下android-studio
咱們從新看一下 DefaultConfig 的繼承結構,能夠看到都會繼承到 BaseConfigImpl
類,說明二者會有必定的交集。這也說明了爲何咱們看 gradle 文件時,總感受一個配置參數哪裏都能出現的狀況(後面會進行更多的比較,來解除咱們這種疑惑)瀏覽器
咱們先來一個約定,避免使用的代碼過於冗長。bash
buildTypes{
debug {
// 咱們下面的 「使用方法」 代碼都是基於這一塊,除非特殊說明。
}
}
複製代碼
debug {
applicationIdSuffix '.debug'
}
複製代碼
library
中,包括咱們以aar形式導入的 library ,或是直接建立的 library。它的做用是,負責該 library 被進行編譯時的混淆規則,咱們在 主App 的模塊下則能夠不用再管理各個 library 的混淆規則,會直接使用各個 library 的混淆規則文件。debug {
consumerProguardFiles 'consumer-rules.pro'
......省略其餘配置
}
// 由於該屬性是一個 List<File> 類型,若是須要多個文件配置,則以下所示
debug {
consumerProguardFiles 'consumer-rules.pro','zincPower-rules.pro'
......省略其餘配置
}
複製代碼
debug {
crunchPngs false
......省略其餘配置
}
複製代碼
debug {
debuggable true
}
複製代碼
annotationProcessor
時所須要的參數。debug {
javaCompileOptions {
annotationProcessorOptions{
arguments = []
classNames ''
....
}
}
......省略其餘配置
}
複製代碼
JavaCompileOptions 能夠配置的具體參數,請進傳送門
debug {
jniDebuggable true
}
複製代碼
AndroidManifest.xml
中使用的參數。debug {
manifestPlaceholders = [APP_LOGO_ICON: "@mipmap/ic_logo"]
}
複製代碼
而後在 AndroidManifest.xml
中使用,使用 ${你配置的變量名}
// 在 application 中使用替換,還須要多添加 tools:replace 這一標籤,將咱們須要替換的名稱寫上,例如這裏的 android:icon
<application android:allowBackup="true" android:icon="${APP_LOGO_ICON}" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" tools:replace="android:icon">
......
複製代碼
debug {
minifyEnabled true
}
複製代碼
minifyEnabled
設置爲 true 的時候會使用這個參數,文件中須要申明哪些文件不被優化和混淆。debug {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
複製代碼
64K 引用限制問題官方文檔 傳送門
android{
buildTypes {
debug {
multiDexEnabled true
...
}
}
}
// 添加依賴
dependencies {
// 若是使用的爲 AndroidX,則使用下面這個導入
// implementation 'androidx.multidex:multidex:2.0.1'
// 若是不使用 AndroidX,則使用下面這段
compile 'com.android.support:multidex:1.0.3'
}
複製代碼
有兩種開啓 MultiDex 方法:
// 第一種:讓你應用的 Application 繼承 MultiDexApplication。
public class MyApplication extends MultiDexApplication {
}
// 第二種:重寫應用的 Application 方法 attachBaseContext
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
複製代碼
最後別忘了在 AndroidManifest.xml
中使用咱們在上面的 Application。
classs.dex
。咱們在第 2.10 小點,分享到使用了多包處理,有時咱們須要將一些主要的類打包進主包,則可使用該屬性。debug {
multiDexKeepFile file('multidex-config.txt')
...
}
複製代碼
multidex-config.txt 中的書寫則以下,每個文件則爲一行
com/example/MyClass.class
com/example/TestClass.class
複製代碼
debug {
multiDexKeepFile file('multidex-config.pro')
...
}
複製代碼
multidex-config.pro 中的寫法以下
// 將會保留全部的在com.example package的類
-keep class com.example.** { *; }
複製代碼
// debug 則會被賦值至 name 屬性,並且 name 是final 類型,沒法在改動。
debug{
...
}
複製代碼
第一步:咱們在配置中開啓該屬性
debug{
pseudoLocalesEnabled true
}
複製代碼
第二步:安裝咱們的應用 第三步:打開設置 -> 系統 -> 語言和輸入法 -> 語言 -> 添加語言
會在 「添加語言」 頁面中看到以下圖的選項,選擇圖中紅色框的內容,各自的不一樣在圖中也有標明,咱們往下走看看具體不一樣的表現是什麼。
小盆友的測試機是 榮耀8,不一樣機子會有些許不一樣
debug {
renderscriptDebuggable true
}
複製代碼
debug {
renderscriptOptimLevel 3
}
複製代碼
shrinkResources 官方使用手冊 傳送門
debug {
shrinkResources false
}
複製代碼
開啓後編譯完會看到以下日誌
SigningConfig 的可配置參數 傳送門
buildTypes {
release {
signingConfig {
// 不建議將簽名證書的信息寫在這裏,而應該是寫在 properties 文件中,將其引入使用
config {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
...
}
}
複製代碼
第一步:在 build.gradle 中開啓 testCoverageEnabled
debug {
testCoverageEnabled true
}
複製代碼
第二步:鏈接上一臺可用設備,由於咱們執行的測試代碼是要基於設備的,若是不鏈接,測試階段會報以下錯
小盆友是 mac 環境,因此 ./gradlew 開頭。windows 的環境則直接使用 gradlew 便可。
./gradlew app:tasks
複製代碼
輸入運行後,能夠看到圖中高亮部分的可運行task。
// create + 你的構建類型名(這裏爲debug) + CoverReport
./gradlew app:cDCR
複製代碼
運行完以後,就是查看測試報告的階段了。咱們進入coverage目錄,具體路徑以下圖所示。
debug {
useProguard true
}
複製代碼
debug {
// 若是 versionName "1.0.0" ,則最終的版本名爲 1.0.0.test
versionNameSuffix ".test"
.....
}
複製代碼
debug {
zipAlignEnabled true
.....
}
複製代碼
matchingFallbacks 還能夠處理 維度風味的 問題,但咱們這裏先不討論,後續的文章會介紹。
一個東西的出現是爲了處理至少一個問題,因此咱們須要先了解下這個問題是怎麼產生的。
此時咱們在項目添加了一個 module 名字爲 library,並依賴進咱們的app中。當咱們構建 「release」、「debug」 兩種版本時,都不會有任何問題,由於 library 默認也提供了 「release」、「debug」 兩種構建版本。
可是當咱們使用 「local」 時,便會出問題了,由於此時 gradle 的腳本也會默認選擇 「library」 的 「local」,但 「library」 中並無。會報下面這樣的錯誤
ERROR: Unable to resolve dependency for ':app@local/compileClasspath': Could not resolve project :lib:library.
Show Details
Affected Modules: app
複製代碼
此時就須要幫 「local」 從 「library」 中選擇一個可用的構建類型,則是經過 matchingFallbacks
進行設置。
鋪墊了這麼多,接下來就是怎麼使用了,在 app 的 build.gradle 中添加以下代碼便可。
local{
matchingFallbacks = ['zinc','release']
...
}
複製代碼
值得一提的是,咱們能夠配置多個,gradle在編譯的時候,會按照從頭開始匹配的原則,例如這裏的 「zinc」 會匹配不到,則匹配 「release」,由於 「release」 匹配到了,則會進行使用,中斷後面的匹配。
// 值的注意的是 value 的值是原樣放置,咱們經過使用方法一節來了解
<type> <name> = <value>
複製代碼
debug {
// 能夠經過 BuildConfig 進行獲取
buildConfigField('String', 'name', '"zinc"')
buildConfigField('int', 'age', '26')
.....
}
複製代碼
最終會生成以下圖的配置,咱們能夠經過下面代碼進行獲取
String name = BuildConfig.name;
int age = BuildConfig.age;
複製代碼
debug {
consumerProguardFile('consumer-rules.pro')
}
複製代碼
debug {
consumerProguardFile('consumer-rules.pro', 'zincPower-rules.pro',.....)
}
複製代碼
debug {
externalNativeBuild {
ndkBuild {
// Passes an optional argument to ndk-build.
arguments "NDK_MODULE_PATH+=../../third_party/modules"
}
// For ndk-build, instead use the ndkBuild block.
cmake {
// Passes optional arguments to CMake.
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
// Sets a flag to enable format macro constants for the C compiler.
cFlags "-D__STDC_FORMAT_MACROS"
// Sets optional flags for the C++ compiler.
cppFlags "-fexceptions", "-frtti"
// Specifies the library and executable targets from your CMake project
// that Gradle should build.
targets "libexample-one", "my-executible-demo"
}
}
}
複製代碼
buildTypes {
debug{
}
local{
// 會拷貝 debug 的配置
initWith debug{
// 在這裏進行咱們本身的配置
}
}
}
複製代碼
debug {
proguardFile 'proguard-rules.pro'
}
複製代碼
debug {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
複製代碼
debug {
proguardFiles = [getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro']
}
複製代碼
debug {
// 添加至 res/value,經過 R.string.age 獲取
resValue('string', 'age', '12 years old')
}
複製代碼
Gradle 的配置文件看起來好像挺亂,實際上是由於咱們沒有進行總體的梳理。不少配置其實不是沒有用,而是咱們沒有對他有一個總體的瞭解,正所謂 「無知最可怕」。
若是喜歡的話請給我一個贊,並關注我吧。文章中若有寫的不妥的地方,請評論區或加我微信與我討論吧,共同進步。
歡迎加我微信,進行更多的交流