標籤:mod app 演算法 項目 storage man header dimens guid
APK檔案只能包含一個AndroidManifest.xml檔案,但Android Studio項目可以包含多個檔案(通過buildSrc、匯入的庫引入)。因此,在構建應用時,Gradle構建會將所有資訊清單檔合并到一個封裝的APK的資訊清單檔中。
資訊清單檔合并優先順序
清單合并工具
- 可以使用Merged Manifest視圖預覽合并清單的效果並找出衝突錯誤。
可以互相合并的基本資訊清單檔,合并優先順序如下(優先順序由高到低):
- 資訊清單檔構建變體
如果變體有多個源集,其清單優先順序由高到低如下:
a、構建變體資訊清單檔(如 src/demoDebug)
b、構建類型清單(如 src/debug/)
c、產品定製清單(如 src/demo/)
如果使用的是定製緯度,清單優先順序與每個維度在 flavorDimensions屬性中的列示順序(優先順序高到低)對應。
- 應用模組的主資訊清單檔
- 所包括庫中的資訊清單檔:如果有多個庫,清單優先順序與依賴順序(庫出現在 Gradle dependencies 塊中的順序)匹配。
重要說明:build.gradle檔案中的構建配置將替換合并資訊清單檔中的任何對應屬性。如build.gradle檔案中的minSdkVersion將替換清單元素中的匹配屬性。
合并衝突啟發學習法演算法
合并工具行為:
- 元素中的屬性絕不合并,僅使用優先順序最高的清單中的屬性。
- 屬性、、元素使用OR合并,因此如果出現衝突,系統將採用“true”並始終包括某個清單所需的功能或者庫。
- 元素始終使用優先順序較高的清單中的值,但以下情況除外:
- 如果低優先順序清單的 minSdkVersion值較高,除非應用 overrideLibrary合并規則。(minSdkVersion使用較大值)
- 如果低優先順序清單的 targetSdkVersion值較低,合并工具將使用高優先順序清單中的值,但也會添加任何必要的系統許可權。(targetSdkVersion使用較大值)
- 絕不會在清單之間匹配元素。每個元素都被視為唯一元素並添加到合并清單中。
重點:清單合并不依賴預設屬性值。因此,應該按照期望明確定義每個屬性。(每個屬性的預設值都會記錄在Manifest reference:https://developer.android.com/guide/topics/manifest/manifest-intro)
合并規則標記
可以針對整個元素或者只對元素中的特定屬性應用標記。
所以標記都屬於Android tools命名空間,因此必須現在元素中聲明此命名空間:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" xmlns:tools="http://schemas.android.com/tools">
節點標記:
- tools:node="merge" ——預設行為,合并此標記中的所有屬性以及所有嵌套元素。
- tools:node="merge-only-attributes" ——僅合并此標記中的屬性,不合并嵌套元素
- tools:node="remove" ——從合并清單中刪除此元素,可以刪除低優先順序清單的元素
- tools:node="removeAll" ——會刪除與此元素類型相匹配的所有元素(同一父元素內)
- tools:node="replace" ——完全替換低優先順序元素
- tools:node="strict" ——標記元素在低優先順序清單中的配置與高優先順序清單不完全符合,會觸發構建失敗。(預設行為會向合并清單添加額外屬性)
屬性標記:
- tools:remove="attr1,attr2,..." ——刪除指定屬性
- tools:replace="attr1,attr2,..." ——替換低優先順序清單指定屬性為當前清單中的屬性
- tools:strict="attr1,attr2,..." ——當指定屬性在低優先順序清單與當前清單中不完全一致,觸發清單合并錯誤。是屬性合并的預設行為。
- 支援對同一個元素使用多個標記
標記選取器:
- tools:selector="lib1,lib2,..." ——針對某個特定的匯入庫應用合并規則標記
- tools:overrideLibrary="lib1,lib2,..." ——替換指定匯入庫的
- 預設情況下,匯入 minSdkVersion值高於主資訊清單檔的庫時會出錯,而且無法匯入該庫。
- 使用 overrideLibrary,可以保持應用的低 minSdkVersion。
隱式系統許可權
隱式許可權:允許應用在無許可權的情況下繼續訪問特定API,前提是應用的targetSdkVersion設定為低於添加限制的SDK版本的值。
原則:
- 如果低優先順序資訊清單檔提供隱式許可權的 targetSdkVersion值較低,而且高優先順序清單沒有相同的隱式許可權,合并工具將向合并清單顯示添加系統許可權。
合并工具可以添加至合并清單的許可權列表:
| 低優先順序清單聲明 |
添加至合并清單的許可權 |
| targetSdkVersion是3或者更低 |
WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE |
| targetSdkVersion是15或者更低,並且使用READ_CONTACTS |
READ_CALL_LOG |
| targetSdkVersion是15或者更低,並且使用WRITER_CONTACTS |
WRITE_CALL_LOG |
具體合并策略:
- 合并:將所有非衝突屬性合并到同一標記中,然後按其各自的合并策略合并子項目。衝突的屬性使用合并規則標記進行合并。
- 僅合并子項:不整合或合并屬性(僅保留高優先順序資訊清單檔提供的屬性)
- 保留
總結
檢查清單合并衝突:在Android Studio中開啟AndroidManifest.xml檔案,單機編輯器底部的 Merged Manifest選項卡。
合并策略:通過合并規則標記設定。
Android資訊清單檔合并的那些事