轉(zhuǎn)載:https://blog.csdn.net/ming54ming/article/details/78766182
每個(gè)構(gòu)建變體都代表您可以為應(yīng)用構(gòu)建的一個(gè)不同版本甥郑。例如俩滥,您可能希望構(gòu)建應(yīng)用的免費(fèi)版本(只提供有限的內(nèi)容)和付費(fèi)版本(提供更多內(nèi)容)迹淌。您還可以針對(duì)不同的設(shè)備屡江、根據(jù) API 級(jí)別或其他設(shè)備變體構(gòu)建應(yīng)用的不同版本沟优。然而巢钓,如果您希望根據(jù)設(shè)備 ABI 或屏幕密度構(gòu)建不同的版本病苗,則請(qǐng)改用 [APK 拆分]
主要是在android {} 代碼塊內(nèi)部創(chuàng)建和配置構(gòu)建類型,其中defaultConfig是一些基本配置症汹,buildTypes就是構(gòu)建類型硫朦,其中默認(rèn)情況下已經(jīng)有了一個(gè)release版本,就是所謂的發(fā)布版本背镇,release{}代碼塊里面就是屬于release版本的一些配置咬展,其實(shí)默認(rèn)情況下應(yīng)該還有一個(gè)debug版本,就是平常的調(diào)試版本瞒斩,只是這里沒有顯示出來(lái)破婆。
配置構(gòu)建類型buildTypes
這里我們來(lái)看一下buildTypes的基本構(gòu)建,
applicationIdSuffix: 是在當(dāng)前applicationId的基礎(chǔ)上拼接剩下的字段形成一個(gè)新的applicationId胸囱,因?yàn)橥粋€(gè)applicationId是無(wú)法同時(shí)運(yùn)行在同一個(gè)手機(jī)上的祷舀,這里也可以直接使用applicationId屬性來(lái)命名新的一個(gè)包名。
initWith:復(fù)制其他buildTypes的內(nèi)容烹笔,這里的jnidebug變體就復(fù)制了debug變體的內(nèi)容裳扯。一般寫法是可以命名一個(gè)默認(rèn)的變體,將一些公共的變量在里面賦值從而給其他變體使用谤职。
配置產(chǎn)品風(fēng)味ProductFlavor
創(chuàng)建產(chǎn)品風(fēng)味與創(chuàng)建構(gòu)建類型類似:只需將它們添加到 productFlavors {} 代碼塊并配置您想要的設(shè)置饰豺。產(chǎn)品風(fēng)味支持與 defaultConfig 相同的屬性,這是因?yàn)?defaultConfig 實(shí)際上屬于 ProductFlavor 類允蜈。這意味著冤吨,您可以在 defaultConfig {} 代碼塊中提供所有風(fēng)味的基本配置,每種風(fēng)味均可更改任何這些默認(rèn)值陷寝,例如 applicationId锅很。
這里可以看到使用和buildTypes類似,具體需要哪些屬性可以查看官網(wǎng)地址凤跑。這里有個(gè)地方應(yīng)該注意的是爆安,編譯類型其實(shí)是buildTyps和productFlavor的組合,這里有三種buildTypes和兩種productFlavor所以最終有6種編譯類型仔引。
在創(chuàng)建和配置您的產(chǎn)品風(fēng)味之后扔仓,在通知欄中點(diǎn)擊 Sync Now褐奥。在同步完成后,Gradle 會(huì)根據(jù)您的構(gòu)建類型和產(chǎn)品風(fēng)味自動(dòng)創(chuàng)建構(gòu)建變體翘簇,并按照 <product-flavor><Build-Type> 的格式命名這些變體撬码。例如,如果您創(chuàng)建了“演示”和“完整”這兩種產(chǎn)品風(fēng)味并保留默認(rèn)的“調(diào)試”和“發(fā)布”構(gòu)建類型版保,Gradle 將創(chuàng)建以下構(gòu)建變體:
- 演示調(diào)試
- 演示發(fā)布
- 完整調(diào)試
- 完整發(fā)布
您可以將構(gòu)建變體更改為您要構(gòu)建并運(yùn)行的任何變體呜笑,只需轉(zhuǎn)到 Build > Select Build Variant,然后從下拉菜單中選擇一個(gè)變體彻犁。然而叫胁,要開始自定義每個(gè)構(gòu)建變體及其功能和資源,您需要了解如何創(chuàng)建和管理源集汞幢。
組合多個(gè)商品風(fēng)味
某些情況下驼鹅,您可能希望組合多個(gè)產(chǎn)品風(fēng)味中的配置。例如森篷,您可能希望基于 API 級(jí)別為“完整”和“演示”產(chǎn)品風(fēng)味創(chuàng)建不同的配置输钩。
為此,您可以通過(guò)適用于 Gradle 的 Android 插件創(chuàng)建產(chǎn)品風(fēng)味組仲智,稱為風(fēng)味維度买乃。
構(gòu)建您的應(yīng)用時(shí),Gradle 會(huì)將您定義的每個(gè)風(fēng)味維度中的產(chǎn)品風(fēng)味配置與構(gòu)建類型配置組合來(lái)創(chuàng)建最終構(gòu)建變體坎藐。Gradle 不會(huì)組合屬于相同風(fēng)味維度的產(chǎn)品風(fēng)味为牍。
flavorDimensions屬性:創(chuàng)建一個(gè)“模式”風(fēng)味維度以組織“完整”和“演示”產(chǎn)品風(fēng)味,以及一個(gè)“api”風(fēng)味維度以基于API級(jí)別組織產(chǎn)品風(fēng)味配置
風(fēng)味維度 | demo | full |
---|---|---|
minApi24 | [minApi24][Demo] | [minApi24][Full] |
minApi23 | [minApi23][Demo] | [minApi23][Full] |
minApi21 | [minApi21][Demo] | [minApi21][Full] |
在 Gradle 為每個(gè)構(gòu)建變體或?qū)?yīng) APK 命名時(shí)岩馍,屬于較高優(yōu)先級(jí)風(fēng)味維度的產(chǎn)品風(fēng)味首先顯示碉咆,之后是較低優(yōu)先級(jí)維度的產(chǎn)品風(fēng)味,再之后是構(gòu)建類型蛀恩。以上面的構(gòu)建配置為例疫铜,Gradle 可以使用以下命名方案創(chuàng)建總共 12 個(gè)構(gòu)建變體:
構(gòu)建變體:[minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
對(duì)應(yīng) APK:app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
例如,
構(gòu)建變體:minApi24DemoDebug
對(duì)應(yīng) APK:app-minApi24-demo-debug.apk
過(guò)濾變體
您可以在模塊級(jí) build.gradle 文件中創(chuàng)建一個(gè)變體過(guò)濾器双谆,以移除某些構(gòu)建變體配置壳咕。
假設(shè)您計(jì)劃為演示版本的應(yīng)用僅支持 API 級(jí)別 23 和更高級(jí)別。您可以使用代碼塊過(guò)濾出組合了“minApi21”和“演示”產(chǎn)品風(fēng)味的所有構(gòu)建變體配置:
android {
...
buildTypes {...}
flavorDimensions "api", "mode"
productFlavors {
demo {...}
full {...}
minApi24 {...}
minApi23 {...}
minApi21 {...}
}
variantFilter { variant ->
def names = variant.flavors*.name
// To check for a certain build type, use variant.buildType.name == "<buildType>"
if (names.contains("minApi21") && names.contains("demo")) {
// Gradle ignores any variants that satisfy the conditions above.
setIgnore(true)
}
}
}
...
創(chuàng)建源集
默認(rèn)情況下顽馋,Android Studio 會(huì)創(chuàng)建 main/ 源集和目錄谓厘,用于存儲(chǔ)在所有構(gòu)建變體之間共享的一切資源。然而寸谜,當(dāng)然也可以創(chuàng)建新的源集來(lái)控制 Gradle 要為特定的構(gòu)建類型竟稳、產(chǎn)品風(fēng)味(以及使用風(fēng)味維度時(shí)的產(chǎn)品風(fēng)味組合)和構(gòu)建變體編譯和打包的確切文件。
例如,可以在 main/ 源集中定義基本的功能他爸,使用產(chǎn)品風(fēng)味源集針對(duì)不同的客戶更改應(yīng)用的品牌聂宾,或者僅針對(duì)使用調(diào)試構(gòu)建類型的構(gòu)建變體包含特殊的權(quán)限和日志記錄功能。
使用步驟如下:
(1)打開 Project 窗格并從窗格頂端的下拉菜單中選擇 Project 視圖诊笤。
(2)導(dǎo)航至 /app/src/系谐。
(3)右鍵點(diǎn)擊 src 目錄并選擇 New > Folder > Java Folder。
(4)從 Target Source Set 旁邊的下拉菜單中讨跟,選擇編譯的版本纪他。
(5)點(diǎn)擊 Finish。
同樣可以用來(lái)創(chuàng)建XML 值文件:
(1)在相同的 Project 窗格中晾匠,右鍵點(diǎn)擊 src 目錄并選擇 New > XML > Values XML File止喷。
(2)為 XML 文件輸入名稱或保留默認(rèn)名稱。
(3)從 Target Source Set 旁邊的下拉菜單中混聊,選擇 編譯的版本。
(4)點(diǎn)擊 Finish乾巧。
更改源集配置
如果您的源未組織到 Gradle 期望的默認(rèn)源集文件結(jié)構(gòu)中句喜,可以
使用 sourceSet{} 代碼塊更改 Gradle 希望為源集的每個(gè)組件收集文件的位置。
下面的代碼示例可以將 app/other/ 目錄中的源映射到 main 源集的某些組件沟于,并更改 androidTest 源集的根目錄咳胃。
android {
...
sourceSets {
// Encapsulates configurations for the main source set.
main {
// Changes the directory for Java sources. The default directory is
// 'src/main/java'.
java.srcDirs = ['other/java']
// If you list multiple directories, Gradle uses all of them to collect
// sources. Because Gradle gives these directories equal priority, if
// you define the same resource in more than one directory, you get an
// error when merging resources. The default directory is 'src/main/res'.
res.srcDirs = ['other/res1', 'other/res2']
// Note: You should avoid specifying a directory which is a parent to one
// or more other directories you specify. For example, avoid the following:
// res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
// You should specify either only the root 'other/res1' directory, or only the
// nested 'other/res1/layouts' and 'other/res1/strings' directories.
// For each source set, you can specify only one Android manifest.
// By default, Android Studio creates a manifest for your main source
// set in the src/main/ directory.
manifest.srcFile 'other/AndroidManifest.xml'
...
}
// Create additional blocks to configure other source sets.
androidTest {
// If all the files for a source set are located under a single root
// directory, you can specify that directory using the setRoot property.
// When gathering sources for the source set, Gradle looks only in locations
// relative to the root directory you specify. For example, after applying the
// configuration below for the androidTest source set, Gradle looks for Java
// sources only in the src/tests/java/ directory.
setRoot 'src/tests'
...
}
}
}
...