資料
優(yōu)先級(jí)
清單文件在合并時(shí),會(huì)按優(yōu)先級(jí)進(jìn)行合并。會(huì)按 優(yōu)先級(jí)從低向高合并,優(yōu)先級(jí)最低的清單文件會(huì)合并到優(yōu)先級(jí)倒數(shù)第二低的文件中,然后今次向下合并。
優(yōu)先級(jí)按高到低如下:
主清單文件。
各庫(kù)中的文件。如果有多個(gè)庫(kù),其清單優(yōu)先級(jí)與依賴順序(庫(kù)出現(xiàn)在 Gradle dependencies 塊中的順序)匹配。
合并規(guī)則
如果優(yōu)先級(jí)較低的清單中的元素與優(yōu)先級(jí)較高的清單中的任何元素均不匹配,則該元素將被添加至合并清單。
如果有匹配元素,則合并工具會(huì)嘗試將其中的所有屬性合并到相同元素中。如果工具發(fā)現(xiàn)兩個(gè)清單包含相同屬性,但值不相同,則會(huì)出現(xiàn)合并沖突。

但如下幾個(gè)標(biāo)簽不會(huì)出現(xiàn)另外:
<manifest> 元素中的屬性絕不合并 — 僅使用優(yōu)先級(jí)最高的清單中的屬性。
-
<uses-sdk>元素始終使用優(yōu)先級(jí)較高的清單中的值,但以下情況除外:
如果低優(yōu)先級(jí)清單的
minSdkVersion值較高,除非您應(yīng)用overrideLibrary合并規(guī)則如果低優(yōu)先級(jí)清單的
targetSdkVersion值 較低,合并工具將使用高優(yōu)先級(jí)清單中的值,但也會(huì)添加任何必要的系統(tǒng)權(quán)限,以確保所導(dǎo)入的庫(kù)繼續(xù)正常工作(適用于較高的 Android 版本具有更多權(quán)限限制的情況)。
<intent-filter> 每個(gè)元素都被視為唯一元素,并添加至合并清單中的常用父元素。也就是說(shuō),<intent-filter> 不會(huì)被合并。
合并規(guī)則標(biāo)記
合并規(guī)則標(biāo)記是一個(gè) XML 屬性,可用于表達(dá)您對(duì)關(guān)于如何解決合并沖突或刪除不需要的元素和屬性的首選項(xiàng)。 您可以對(duì)整個(gè)元素或只對(duì)元素中的特定屬性應(yīng)用標(biāo)記。
合并兩個(gè)清單文件時(shí),合并工具會(huì)在高優(yōu)先級(jí)清單文件中尋找這些標(biāo)記。
所有的標(biāo)識(shí)分為兩種類型,一種作用于節(jié)點(diǎn),一種作用于屬性。
節(jié)點(diǎn)標(biāo)記
作用于整個(gè) xml 元素。其對(duì)應(yīng)的屬性名為 node。值如下:
| 屬性值 | 含義 |
|---|---|
| merge | 合并此標(biāo)記中的所有屬性以及所有嵌套元素 |
| merge-only-attributes | 只合并屬性,不合并子元素 |
| remove | 刪除匹配的元素 |
| removeAll | 刪除所有匹配的標(biāo)簽 |
| replace | 忽略低優(yōu)先級(jí)內(nèi)容,完全使用高優(yōu)先級(jí)內(nèi)容 |
| strict | 只要兩個(gè)清單文件不一樣,無(wú)論是否能合并,都會(huì)出現(xiàn)沖突 |
在比對(duì)元素是否相同時(shí),只比例標(biāo)簽名以及其中的 name 屬性值。如果都相同,則認(rèn)為相同;否則不相同。
merge
默認(rèn)行為。合并此標(biāo)記中的所有屬性以及所有嵌套元素。如
低版本為:
<activity android:name="com.demo.MainActivity"
android:hardwareAccelerated="false" >
<meta-data
android:name="test"
android:value="test" />
</activity>
高版本為
<activity
android:name="com.demo.MainActivity"
android:screenOrientation="portrait"
tools:node="merge">
</activity>
則合并后為:
<activity
android:name="com.demo.MainActivity"
android:screenOrientation="portrait"
android:hardwareAccelerated="false">
<meta-data
android:name="test"
android:value="test" />
</activity>
merge-only-attributes
僅合并元素的屬性,不合并子元素。
remove
刪除滿足條件的元素。
如高版本配置如下:
<meta-data android:name="test"
android:value="main"
tools:node="remove" />
則合并后的清單文件中不會(huì)含有該 meta-data。
removeAll
刪除所有標(biāo)配的標(biāo)簽。使用該屬性值時(shí),標(biāo)簽中不能含有任何其他屬性,也就是說(shuō)該標(biāo)簽中除了 tools:node="removeAll" 外,不能配置任何其他屬性。
<meta-data
android:name="test"
tools:node="removeAll" />
上述配置會(huì)刪除同一父元素內(nèi)的所有 <meta-data> 標(biāo)簽。
replace
完全替換低優(yōu)先級(jí)元素。 也就是說(shuō),如果低優(yōu)先級(jí)清單中有匹配元素,請(qǐng)將其忽略并完全按照其在此清單中顯示樣子來(lái)使用該元素。
標(biāo)簽匹配不單指標(biāo)簽名相同,其 name 元素的值也要相同。
<meta-data
android:name="test"
tools:node="replace" />
strict
當(dāng)此元素在低優(yōu)先級(jí)清單中的情況與在高優(yōu)先級(jí)清單中的情況不完全匹配時(shí)生成構(gòu)建故障。如:
<!---高優(yōu)先級(jí)-->
<activity
tools:node="strict"
android:name="com.example.ActivityOne"
android:windowSoftInputMode="stateUnchanged">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!--低優(yōu)先級(jí)-->
<activity
android:name="com.example.ActivityOne"
android:screenOrientation="portrait" />
上述兩個(gè)文件在合并時(shí),會(huì)產(chǎn)生沖突;但如果將 strict 換成 merge 會(huì)合并成功。
屬性標(biāo)記
屬性標(biāo)記只會(huì)影響某個(gè) xml 標(biāo)簽中的某個(gè)屬性,不會(huì)影響整個(gè)標(biāo)簽。
每個(gè)屬性接受一個(gè)或多個(gè)屬性名稱(包括屬性命名空間),并以逗號(hào)分隔。
replace
將低優(yōu)先級(jí)清單中的指定屬性替換為此清單中的屬性。 換言之,始終保持高優(yōu)先級(jí)清單的值
<!--高版本-->
<meta-data
android:name="test"
android:resource="@string/test"
android:value="main"
tools:replace="android:value,android:resource" />
<!--低版本-->
<meta-data
android:name="test"
android:resource="@string/app_name"
android:value="test" />
首先,replace 的值是 android:value,而不是 value。也就是說(shuō):在 配置屬性名時(shí),需要帶名稱空間。
其次,replace 可以配置多個(gè)屬性,屬性之間通過(guò)逗號(hào)分隔。
上述文件合并后,得到的依舊是高版本的配置。
remove
從合并清單中刪除指定屬性。
<!--高版本-->
<meta-data
android:name="test"
android:value="main"
tools:remove="android:resource" />
<!--低版本-->
<meta-data
android:name="test"
android:resource="@string/app_name" />
<!--合并結(jié)果-->
<meta-data
android:name="test"
android:value="main" />
因?yàn)樵诟邇?yōu)先級(jí)中使用了 remove,則合并后不會(huì)出現(xiàn) android:resource 屬性。
strict
當(dāng)這些屬性在低優(yōu)先級(jí)清單中的情況與在高優(yōu)先級(jí) 清單中的不完全匹配時(shí)生成構(gòu)建故障。 默認(rèn)行為。
選擇器
僅對(duì)某個(gè)特定的導(dǎo)入庫(kù)應(yīng)用合并規(guī)則標(biāo)記,需要使用 tools:selector 屬性。
例如,對(duì)于下面的清單,僅在低優(yōu)先級(jí)清單文件來(lái)自 com.example.lib1 庫(kù)時(shí)應(yīng)用 remove 合并規(guī)則。
<permission android:name="permissionOne"
tools:node="remove"
tools:selector="com.example.lib1">
如果低優(yōu)先級(jí)清單來(lái)自其他源,系統(tǒng)將會(huì)忽略 remove 合并規(guī)則。
<uses-sdk>
默認(rèn)時(shí),如果庫(kù)的 minSdk 高于主工程的,則會(huì)出錯(cuò),無(wú)法導(dǎo)入該庫(kù)。可以將 overrideLibrary 添加至 <uses-sdk> 標(biāo)簽中。
overrideLibrary 屬性值可以是一個(gè)或多個(gè)庫(kù)的包名(以逗號(hào)分隔),指明可能替換主清單的 minSdkVersion 的庫(kù)。
如主工程設(shè)置 minSdk 為 21, library 設(shè)置為 22。則合并時(shí)會(huì)出現(xiàn)錯(cuò)誤??梢栽谥鞴こ痰那鍐挝募刑砑尤缦屡渲茫?/p>
<uses-sdk tools:overrideLibrary="com.library.package" />
其中 com.library.package 替換為庫(kù)的包名。