AndroidManifest合并原理

3.11 AndroidManifest合并原理

Android Studio工程通常包含多個AndroidManifest文件,最終構建成APK時,會合并成一個AndroidManifest文件。但是可能很多人應該都不知道是怎么合并的,本文將為大家揭開神秘面紗。

3.11.1 合并沖突規(guī)則(merge conflict rules)

合并沖突,是指多個Manifest文件中含有同一屬性但值不同時,默認合并規(guī)則解決不了從而導致的沖突。當沖突發(fā)生時,高優(yōu)先級的Manifest屬性值會覆蓋低優(yōu)先級屬性值。這個優(yōu)先級規(guī)則由高到低依次是:

buildType下的Manifest設置->productFlavor下的Manifest設置->主工程src/main->dependency&library

默認合并沖突規(guī)則如下:

當然還存在例外情況:

  • uses-feature android:required和uses-library android:required默認值都是true,根據(jù)OR規(guī)則合并
  • 如果不指定uses-sdk,默認的minSdkVersion和targetSdkVersion值為1,當發(fā)生沖突時將使用高優(yōu)先級的值。若不指定targetSdkVersion,其值等于targetSdkVersion
  • 當library工程的minSdkVersion比主工程src/main中的minSdkVersion低時會產生沖突,此時需要添加overLibrary標記解決沖突
  • 當library工程的targetSdkVersion比主工程src/main中的大時,合并過程會增加一些權限保證library工程能正常運行
  • 每個Manifest文件只和其子Manifest文件的屬性合并
  • <intent-filter>的合并規(guī)則是疊加而不是覆蓋

3.11.2 合并沖突標記和選擇器(merge conflict marker&selector)

合并沖突標記,是android tools namespace中的一個屬性,用來解決默認沖突規(guī)則解決不了的沖突。主要包含以下幾個:

  • merge:默認合并操作。
  • replace:高優(yōu)先級替換低優(yōu)先級Manifest文件中的屬性
  • strict:屬性相同而值不同時會報錯,除非通過沖突規(guī)則解決了
  • merge-only:僅合并低優(yōu)先級的屬性
  • remove:移除指定的低優(yōu)先級的屬性
  • remove-All:移除相同節(jié)點類型下所有低優(yōu)先級的屬性

一般節(jié)點層面默認使用merge,屬性層面默認使用strict。下面看幾個例子:

  1. 使用replace標記解決android:icon和android:label屬性沖突
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.android.tests.flavorlib.app"
   xmlns:tools="http://schemas.android.com/tools">

   <application
       android:icon="@drawable/icon"
       android:label="@string/app_name"
       tools:replace="icon, label">
       ...
   </application>
</manifest>
  1. 以下代碼塊中,src manifest會覆蓋library的<uses-sdk>。(默認情況下是不允許低優(yōu)先級的minSdkVersion大于高優(yōu)先級的,否則會報錯。)
//src manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.android.example.app"
   xmlns:tools="http://schemas.android.com/tools">
   ...
   <uses-sdk android:targetSdkVersion="22" android:minSdkVersion="2"
         tools:overrideLibrary="com.example.lib1, com.example.lib2"/>
   ...
</manifest>
//Library manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.lib1">
    ...
    <uses-sdk android:minSdkVersion="4" />
    ...
</manifest>
  1. 以下代碼塊表示,移除library1中的permissionOne權限,而其他模塊下該權限不受影響。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.android.example.app"
   xmlns:tools="http://schemas.android.com/tools">
   ...
   <permission
       android:name="permissionOne"
       tools:node="remove"
       tools:selector="com.example.lib1">
       ...
   </permission>
</manifest>

3.11.3 向AndroidManifest文件注入build變量值

注入build變量值通常需要使用manifestPlaceholders,applicationId屬性除外。另外支持部分注入,如android:authority="com.acme.${localApplicationId}.foo"。仍然是看幾個例子:

  1. 注入applicationId
<activity android:name=".Main">
    <intent-filter>
        <action android:name="${applicationId}.foo"></action>
    </intent-filter>
</activity>

Gradle build file:

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    productFlavors {
        flavor1 {
            applicationId = "com.mycompany.myapplication.productFlavor1"
        }
    }
    ...
}

注入之后的manifest為:

<action android:name="com.mycompany.myapplication.productFlavor1.foo"/>
  1. 注入其他屬性
    Gradle build file:
android {
    defaultConfig {
        manifestPlaceholders = [ activityLabel:"defaultName"]
    }
    productFlavors {
        free {
        }
        pro {
            manifestPlaceholders = [ activityLabel:"proName" ]
        }
    }
    ...
}

Placeholder in the manifest file:

<activity android:name=".MainActivity" android:label="${activityLabel}" />
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,267評論 25 708
  • Android Studio工程通常包含多個AndroidManifest文件,最終構建成APK時,會合并成一個A...
    某學姐閱讀 8,921評論 1 10
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,665評論 19 139
  • Gradle是什么? Android Studio 基于 Gradle 構建系統(tǒng),并通過 Android Grad...
    CP9閱讀 1,308評論 0 3
  • 通州小學 六(12)班 陳果兒 親愛的媽媽,這次去內蒙古旅行,我想帶上《火印》這本書,我想看看內蒙古大草原與...
    負暄jxy閱讀 793評論 1 3

友情鏈接更多精彩內容