編輯:關於android開發
使用Android Studio並且基於Gradle構建,每個App能在多個位置包含清單文件,例如在src/main文件夾下productFlavor、庫、Android ARchive(AAR) bundles of Android Library項目,和第三方依賴。在構建過程中,包含在你的app中的多個AndroidMainfest.xml設置合並成一個,生成APK清單文件用於app的打包和發布。清單文件的設置基於清單優先級來合並,取決於清單文件的位置。從制定build variant清單文件的元素,屬性,和子元素構建合並你的app清單文件。
合並沖突規則
------------------------------------------------------------------
合並的沖突發生在清單文件包含相同的清單元素,並且有不同的屬性值,無法使用默認的合並規則解決的時候。Conflict markers和selectors也能定義自定義的合並規則,例如允許一個導入的庫有一個minSdkVersion大於在其它更高優先級清單中定義的版本。
清單合並優先級決定了哪個清單設置在合並沖突中保留,使用高優先級訂單文件設置覆蓋低優先級清單。下面的列表詳細描述了在合並過程中,哪個清單設置的優先級最高:
最高優先級:buildType清單設置
高優先級:productFlavor清單設置
中優先級:app項目在src/main/目錄下清單
低優先級:依賴和庫清單設置
清單沖突合並基於下面的合並規則在XML節點和屬性級別被解決:
清單合並規則例外:
uses-feature android:required;和use-library android:required元素默認值為true,並且使用一個或者合並,這樣任何要求的功能和庫在成成的APK都被包含。
如果沒有聲明,
導入一個包含minSdkVersion值高於app的src/main/清單文件,清單產生一個錯誤,除非overrideLibrary沖突記號被使用;
注意:如果沒有明確的聲明,targetSdkVersion默認為minSdkVersion值。當沒有元素在任何清單文件或者build.gradle文件中出現的時候,minSdkVersion默認為1。
當導入一個包含targetSdkVersion值低於app的src/main清單文件的庫,清單合並過程明確授予權限並,並確保正確的導入庫庫函數。
manifest元素僅僅合並孩子清單元素。
intent-filter元素從不改變並且總是添加到合並的清單相同的父節點下。
重要:在清單文件被合並後,構建過程使用build.gradle文件中的任何設置覆蓋最終的清單設置。更多詳情,請閱讀Configure Gradle Builds。
合並沖突標記和選擇器
------------------------------------------------------------------
清單標記和選擇器通過制定沖突解決辦法覆蓋默認的規則。例如,使用沖突標識來合並一個庫清單的minSdkVersion高於更高優先級清單,或者合並清單相同的Activity,但是不同的android:theme值。
合並沖突標識
一個合並沖突標識是一個在Android工具空間的指定元素,它定義了一個指定的沖突合並方案。創建一個沖突標識是為了避免使用默認合並規則沒有解決的合並沖突錯誤。支持的合並沖突標識包括:
merge
當沒有合並規則沖突的時候合並屬性。默認的合並動作。
replace
使用高優先級的清單替代低優先級清單中的屬性;
strict
merge-only
允許指定低優先級屬性的合並動作;
remove
刪除合並後的清單指定的低級別元素;
remove-All
刪除合並後清單的相同節點類型的所有低優先級元素;
默認情況下,清單的合並過程在節點級別應用merge沖突標識。所有聲明的清單屬性默認是strict合並策略。
為了設置一個合並沖突標識,首先在AndroidManifest.xml文件中聲明命名空間。然後在清單中輸入合並沖突標識的一個指定的合並沖突動作。這個例子插入了replace標識來設置一個replace動作,來解決在android:icon和android:lable清單元素的沖突。
...
標記屬性
沖突標識使用tools:node和tools:attr屬性來在XML節點或者屬性級別的沖突動作。
tools:attr標識僅僅使用restrict,remove,和replace合並動作。多個tools:attr標識的值可以被應用到一個指定的元素。例如,使用tools:replace="icon,lable,theme"來提來更低的優先級icon,lable和theme屬性。
向清單文件中注入構建值
-----------------------------------------------------------------
清單文件合並也能使用清單占位符,從build.gradle文件向清單屬性注入屬性值。
清單占位符使用這個語法${name}設置屬性值,name是注入build.gradle屬性,build.gradle文件使用manifestPlaceholders屬性來定義占位符的值。
注意:在app中未解析的占位符名稱會導致構建失敗。在庫中未解析的占位符生成警告,並且將這個庫導入一個app的時候必須解決。
這個例子展示了清單占位符${applcationId}用於映射build.gradle的applicationID屬性值到android:name屬性值。
注意:Android Studio為build.gradle applicationID值提供了一個默認的${applicationId}占位符,它不顯示在構建文件中。當為庫模塊構建一個AAR(Android ARchive)包時,不需要在清單合並設置中提供一個自動的@{applicationID}占位符。相反,使用一個不同的占位符,例如@{libApplicationID},並為如果你想包括歸檔庫的appliction Id,為它提供一個值。
清單實體:
構建文件:
android { compileSdkVersion 22 buildToolsVersion "22.0.1" productFlavors { flavor1 { applicationId = "com.mycompany.myapplication.productFlavor1" } }合並清單值:
清單文件占位符和構建文件manifestPlaceholders屬性能被用於注入其它清單文件值。對於applicationId依賴的屬性,manifestPlaceholders屬性明確的在build.gradle文件中聲明。這個例子展示了清單占位符注入activityLabel值。
Gradle build 文件:
android { defaultConfig { manifestPlaceholders = [ activityLabel:"defaultName"] } productFlavors { free { } pro { manifestPlaceholders = [ activityLabel:"proName" ] } }構建文件:
android { defaultConfig { manifestPlaceholders = [ activityLabel:"defaultName"] } productFlavors { free { } pro { manifestPlaceholders = [ activityLabel:"proName" ] } }
注意:占位符的值支持部分值注入,例如android:authority="com.acme.${localApplicationId}.foo".
通過Product Flavor組合並清單文件
-----------------------------------------------------------------
當使用GroupbleProductFlavor屬性,任何在Product flavor組的清單文件的合並優先級取決於在構建文件中的排列順序。清單文件合並的過程基於build variant的構建配置,為product flavor組創建一個單獨合並清單文件。
例如,如果一個build varian從各自的product flavor組ABI,Density,API和Prod參考了product flavors x86,mdpi,21,和paid,在build.gradle文件中以該順序排列,然後清單文件以product flavors在構建文件中排列的順序為優先級合並。
為了說明這個例子,下面的標識展示了每個product flavor組列舉了什麼product flavor。這個product flavors和組的組合定義了build variant。
Product Flavor Group
Product Flavor
ABI
x86
density
mdpi
API
22
prod
paid
清單合並順序:
prod-paid AndroidManifest.xml(低優先級)合並到API-22 AndroidManifest.xml
API-22 AndroidManifest.xml合並到density-mpi AndroidManifest.xml
density-mpi AndroidManifest.xml合並到ABI-x86 AndroidManifest.xml(高優先級)
隱式權限
-----------------------------------------------------------------
導入一個支持隱式授予權限的Android運行的庫,可能會自動往合並清單中添加這個權限。例如,如果一個targetSdkVersion為16的應用程序,導入一個targetSdkVersion為2的庫,Andorid Studio添加WRITE_EXTERNAL_STORAGE權限,以確保跨SDK版本的兼容性。
注意:更多現在的Android版本取代隱式的權限聲明。
Importing this library version
Declares this permission in the manifest
targetSdkVersion < 2
WRITE_EXTERNAL_STORAGE
targetSdkVersion < 4
WRITE_EXTERNAL_STORAGE,READ_PHONE_STATE
Declared WRITE_EXTERNAL_STORAGE
READ_EXTERNAL_STORAGE
targetSdkVersion < 16 and using the READ_CONTACTS permission
READ_CALL_LOG
targetSdkVersion < 16 and using WRITE_CONTACTS permission
WRITE_CALL_LOG
處理清單合並構建錯誤
------------------------------------------------------------------
在構建過中,清單合並過程在模塊的build/outputs/logs目錄下mainfest-merge-
當一個清單合並構建錯誤發生的時候,構建過程在日志文件中記錄了描述合並沖突錯誤消息。例如,在下面的清單之間導致了一個構建錯誤android:screenOrientation合並沖突。
高優先級的清單聲明:
低優先級的清單聲明:
錯誤日志:
/project/app/src/main/AndroidManifest.xml:3:9 Error: Attribute activity@screenOrientation value=(portrait) from AndroidManifest.xml:3:9 is also present at flavorlib:lib1:unspecified:3:18 value=(landscape) Suggestion: add 'tools:replace="icon"' to element at AndroidManifest.xml:1:5 to override
Android應用自定義View繪制方法手冊 背景 這篇遲遲難產的文章算是對2015前半年的一個交代吧,那時候有一哥們要求來一發Android Canvas相關總結,這哥
【原創】可以換行的RadioGroup,換行radiogroup0、效果截圖: 以上兩個RadioGroup均使用FNRadioGroup實現。 1、控件
Android代碼故事第一回,平均間隔的按鈕,android第一回我們的APP新做了一個放操作按鈕的界面,老板要求簡潔美觀有內涵,按鈕要均勻分布,於是參考之前的實現,設計
TCPCOPY 1.0 安裝使用TCPCOPY 1.0 安裝使用簡介TCPCOPY 是一個 tcp 流量的實時復制工具,其1.0版本由網易工程師 @tcpcopy 開發和