一、源集
1、定義:Android Studio 按邏輯關(guān)系將每個(gè)模塊的源代碼和資源進(jìn)行分組,這個(gè)分組叫做源集。
2、main Module 源集包括其所有構(gòu)建變體共用的代碼和資源。這句話很關(guān)鍵,意思是,所有的其他構(gòu)建變體,src/main是其共同擁有的。在說明BuildType時(shí),我們會(huì)通過案例代碼進(jìn)行介紹。
3、其他源集目錄為可選項(xiàng),在您配置新的構(gòu)建變體時(shí),Android Studio 不會(huì)自動(dòng)為您創(chuàng)建這些目錄,用戶可以通過File > New 菜單選項(xiàng)新建文件或目錄,進(jìn)行特定源集進(jìn)行創(chuàng)建。
源集按照構(gòu)建類別(buildType)、產(chǎn)品傾向(productFlavor)等,分為以下幾個(gè)類型:
| 源集 | 備注 |
|---|---|
| src/main/ | 此源集包括所有構(gòu)建變體共用的代碼和資源。 |
| src/<buildType>/ | 創(chuàng)建此源集可加入特定構(gòu)建類型專用的代碼和資源。 |
| src/<productFlavor>/ | 創(chuàng)建此源集可加入特定產(chǎn)品風(fēng)味專用的代碼和資源。 |
| src/<productFlavorBuildType>/ | 創(chuàng)建此源集可加入特定構(gòu)建變體專用的代碼和資源。 |
例如,要生成應(yīng)用的“完整調(diào)試”版本,構(gòu)建系統(tǒng)需要合并來自以下源集的代碼、設(shè)置和資源:
src/fullDebug/(構(gòu)建變體源集)
src/debug/(構(gòu)建類型源集)
src/full/(產(chǎn)品風(fēng)味源集)
src/main/(主源集)
4、源集的Overlay機(jī)制。如果不同源集包含同一文件的不同版本,Gradle 將按以下優(yōu)先順序決定使用哪一個(gè)文件(左側(cè)源集替換右側(cè)源集的文件和設(shè)置):
構(gòu)建變體 > 構(gòu)建類型[BuildType] > 產(chǎn)品風(fēng)味[ProductFlavor] > 主源集[main] > 庫依賴項(xiàng)
在合并多個(gè)清單時(shí),Gradle 會(huì)使用專用于試圖構(gòu)建的資源進(jìn)行編譯,這些文件包括:構(gòu)建變體的文件,其他應(yīng)用版本共用的 Activity、應(yīng)用邏輯和資源,從而達(dá)到不同的構(gòu)建,編譯不同的資源的目的。
二、源集的創(chuàng)建
Gradle 會(huì)按照與 main/ 源集類似的特定組織形式來管理源集文件和目錄。例如,Gradle 要求您的“調(diào)試”構(gòu)建類型所特定的 Java 類文件位于 src/debug/java/ 目錄中。
以debug為例,源集構(gòu)建會(huì)有如下幾種方式:
方式一:
1、打開 Project 窗格并從窗格頂端的下拉菜單中選擇 Project 視圖。
2、導(dǎo)航至 MyProject/app/src/。
3、右鍵點(diǎn)擊 src 目錄并選擇 New > Folder > Java Folder。
4、從 Target Source Set 旁邊的下拉菜單中,選擇 debug。
5、點(diǎn)擊 Finish。
方式二:
1、在相同的 Project 窗格中,右鍵點(diǎn)擊 src 目錄并選擇 New > XML > Values XML File。
2、為 XML 文件輸入名稱或保留默認(rèn)名稱。
3、從 Target Source Set 旁邊的下拉菜單中,選擇 debug。
4、點(diǎn)擊 Finish。

以上兩種方式,都可以創(chuàng)建源集,源集成功創(chuàng)建后,工程展示如下:

三、源集的重定向
可以通過sourceSets {}來設(shè)定Gradle module對應(yīng)的源集路徑。
Android SourceSet表示Java,aidl和RenderScript源以及Android和非Android(Java風(fēng)格)資源的邏輯組。
3.1、屬性
| 屬性 | 描述 |
|---|---|
| aidl | Android AIDL源目錄為此源設(shè)置。 |
| assets | 該資源集的Android Assets目錄。 |
| compileConfigurationName | 該源集合的編譯配置的名稱。 |
| java | Java源代碼由Java編譯器編譯到類輸出目錄中。 |
| jni | 這個(gè)源碼集的Android JNI源目錄。 |
| jniLibs | 這個(gè)源碼集的Android JNI libs目錄。 |
| manifest | 該源代碼集的Android Manifest文件。 |
| name | 這個(gè)源集的名稱。 |
| packageConfigurationName | 此源集合的運(yùn)行時(shí)配置的名稱。 |
| providedConfigurationName | 此源集合的僅編譯配置的名稱。 |
| renderscript | 該源碼集的Android RenderScript源目錄。 |
| res | 該資源集的Android資源目錄。 |
| resources | 要復(fù)制到j(luò)avaResources輸出目錄的Java資源。 |
3.2、方法
| 方法 | 描述 |
|---|---|
| setRoot(path) | 將源集的根設(shè)置為給定的路徑。源集合的所有條目都位于此根目錄下。 |
更多屬性以及方法詳情,請參與官方文檔
案例配置: 配置app/other/目錄中的源映射到 main源集的某些組件,并更改 androidTest 源集的根目錄。
android {
...
sourceSets {
// main源集(source set)的閉包配置。
main {
// 變更Java 的源文件夾,默認(rèn)的文件夾 = 'src/main/java'.
java.srcDirs = ['other/java']
//如果像以下方式一樣,列出來多個(gè)文件夾,那么Gradle使用所有的這些文件夾來加載資源,
//并賦予這些文件夾相同的優(yōu)先級(jí)。如果不同的文件夾中定義了相同的資源,那么會(huì)產(chǎn)生資源合并錯(cuò)誤。
//默認(rèn)的資源文件夾是 'src/main/res'.
res.srcDirs = ['other/res1', 'other/res2']
//避免多個(gè)文件夾出現(xiàn)“父子”依賴關(guān)系。例如:如下情況要避免:
//res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
//應(yīng)該只指定:'other/res1'或者指定'other/res1/layouts' and 'other/res1/strings'
//每個(gè)源集只能有一個(gè)AndroidManifest.xml清單文件,
//默認(rèn)情況下,main源集的清單文件在src/main/ 目錄中。
manifest.srcFile 'other/AndroidManifest.xml'
...
}
// 創(chuàng)建額外閉包塊區(qū)配置其他源集
androidTest {
// 如果所有的源集文件都在一個(gè)單獨(dú)的目錄中,可以使用setRoot來進(jìn)行配置。
// 這樣子,Gradle就只會(huì)加載該區(qū)域。例如:如下配置,Gradle只會(huì)從src/tests/java/
// 來獲取源集文件。
setRoot 'src/tests'
...
}
}
}
...
四、源集的使用
在使用源集進(jìn)行編譯的時(shí)候,要特別注意資源合并的優(yōu)先級(jí)的問題。上面也提到了,優(yōu)先級(jí)如下:
構(gòu)建變體 > 構(gòu)建類型[BuildType] > 產(chǎn)品風(fēng)味[ProductFlavor] > 主源集[main] > 庫依賴項(xiàng)
詳細(xì)說明如下:
-
Java文件。如果找到兩個(gè)或兩個(gè)以上定義相同Java 類名的源集目錄,那么Gradle 就會(huì)引發(fā)一個(gè)構(gòu)建錯(cuò)誤。
例如,在構(gòu)建調(diào)試 APK 時(shí),同時(shí)定義 src/debug/Utility.java 和 src/main/Utility.java,會(huì)發(fā)生編譯錯(cuò)誤。 這是因?yàn)镚radle 在構(gòu)建中檢查這兩個(gè)目錄并引發(fā)了“duplicate class”錯(cuò)誤。 - 清單合并為單個(gè)清單。在合并清單時(shí),將按照上述列表中的順序指定優(yōu)先級(jí)。也就是說,某個(gè)構(gòu)建類型的清單設(shè)置會(huì)替換某個(gè)產(chǎn)品風(fēng)味的清單設(shè)置,依此類推。
- value資源。values/ 目錄中的文件也會(huì)合并在一起。如果兩個(gè)文件同名,例如存在兩個(gè) strings.xml 文件,將按照上述列表中的相同順序指定優(yōu)先級(jí)。也就是說,某個(gè)源集文件中定義的值將會(huì)替換產(chǎn)品風(fēng)味中同一文件中定義的值,依此類推。
- res/ 和 asset/ 目錄中的資源將打包到一起。如果兩個(gè)或兩個(gè)以上的源- 集中定義有同名資源,將按照上述列表中的相同順序指定優(yōu)先級(jí)。
- 最后,在構(gòu)建 APK 時(shí),Gradle 會(huì)為隨庫模塊依賴項(xiàng)包含的資源和清單分配最低的優(yōu)先級(jí)。
寫作不易,耗費(fèi)心力,如果上面的內(nèi)容對你有幫助,請隨意打賞,讓我們堅(jiān)持下去~