The Android Developer Challenge is back! Submit your idea before December 2.

다중 manifest 파일 병합

APK 파일은 하나의 AndroidManifest.xml 파일만 포함할 수 있지만 Android 스튜디오 프로젝트는 기본 소스 세트, 빌드 변형 및 가져온 라이브러리에서 제공하는 여러 파일을 포함할 수 있습니다. 그러므로 앱을 빌드할 때 Gradle 빌드는 모든 manifest 파일을 하나의 manifest 파일로 병합하며 이 파일은 APK에 패키징됩니다.

manifest 병합 도구는 병합 추론과 특수 XML 속성으로 정의한 병합 기본 설정에 따라 각 파일에서 모든 XML 요소를 결합합니다. 이 페이지는 manifest 병합의 원리와 병합 기본 설정을 병합 충돌 해결에 적용하는 방법을 설명합니다.

팁: 병합된 manifest를 사용하여 병합된 manifest 결과를 미리 보고 충돌 오류를 찾으세요.

병합 우선순위

병합 도구는 각 manifest 파일의 우선순위에 따라 모든 manifest 파일을 하나의 파일로 순차 병합합니다. 예를 들어 manifest 파일이 3개 있을 경우 그림 1과 같이 우선순위가 가장 낮은 manifest가 다음으로 우선순위가 높은 파일과 병합되고, 이렇게 병합된 파일은 가장 우선순위가 높은 파일과 병합됩니다.

그림 1. 우선순위가 가장 낮은 파일(왼쪽)을 가장 높은 파일(오른쪽)로 manifest 파일 3개를 병합하는 과정

서로 병합할 수 있는 기본적인 manifest 파일 유형은 3가지가 있습니다. 각 유형의 병합 우선순위는 다음과 같습니다(우선순위가 높은 순).

  1. 빌드 변형용 manifest 파일

    변형용 소스 세트가 여러 개 있는 경우 manifest 우선순위는 다음과 같습니다.

    1. 빌드 변형 manifest(예: src/demoDebug/)
    2. 빌드 유형 manifest(예: src/debug/)
    3. 제품 버전 manifest(예: src/demo/)

      버전 차원을 사용 중인 경우 manifest 우선순위는 flavorDimensions 속성에 각 차원이 나열되는 순서(우선순위가 높은 순)와 같습니다.

  2. 앱 모듈의 기본 manifest 파일
  3. 포함된 라이브러리의 manifest 파일

    라이브러리가 여러 개 있는 경우 manifest 우선순위는 종속성 순서(Gradle dependencies 블록에 나타나는 순서)와 일치합니다.

예를 들어 라이브러리 manifest는 기본 manifest와 병합되고 기본 manifest는 빌드 변형 manifest와 병합됩니다.

중요: build.gradle 파일의 빌드 구성은 병합된 manifest 파일의 해당하는 속성을 재정의합니다. 예를 들어 build.gradle 파일의 minSdkVersion<uses-sdk> manifest 요소의 매칭 속성을 재정의합니다. 혼란을 피하기 위해 <uses-sdk> 요소는 제외하고 build.gradle 파일에서만 이러한 속성을 정의해야 합니다. 자세한 내용은 빌드 구성을 참조하세요.

병합 충돌 추론

병합 도구는 특정 manifest의 모든 XML 요소를 다른 manifest의 해당하는 요소와 논리적으로 매칭할 수 있습니다. 매칭 원리에 관한 자세한 내용은 병합 정책 관련 부록을 참조하세요.

낮은 우선순위의 manifest 요소는 높은 우선순위 manifest의 요소와 일치하지 않는 경우 병합된 manifest에 추가됩니다. 그러나 일치하는 요소가 있으면 병합 도구는 각 요소의 모든 속성을 동일한 요소로 결합하려고 시도합니다. 두 개의 manifest에 값이 다른 동일한 속성이 포함된 것이 발견되면 병합 충돌이 발생합니다.

표 1은 병합 도구가 모든 속성을 동일한 요소로 결합할 때 나올 가능성이 있는 결과를 보여줍니다.

표 1. 속성 값의 기본 병합 동작

우선순위가 높은 속성 우선순위가 낮은 속성 속성의 병합된 결과
값 없음 값 없음 값 없음(기본값 사용)
값 B 값 B
값 A 값 없음 값 A
값 A 값 A
값 B 충돌 오류 - 병합 규칙 마커를 추가해야 함

그러나 병합 충돌을 피하기 위해 병합 도구가 다른 방식으로 동작하는 경우가 몇 가지 있습니다.

  • <manifest> 요소의 속성은 절대 함께 병합되지 않습니다. 우선순위가 가장 높은 manifest의 속성만 사용됩니다.
  • <uses-feature><uses-library> 요소의 android:required 속성은 OR 병합을 사용하므로, 충돌이 발생할 경우 "true"가 적용되고 하나의 manifest에 필요한 기능 또는 라이브러리는 언제나 포함됩니다.
  • <uses-sdk> 요소의 속성은 항상 우선순위가 높은 manifest의 값을 사용합니다. 단, 다음 상황은 예외입니다.
    • 우선순위가 낮은 manifest에 더 높은 minSdkVersion 값이 있는 경우, overrideLibrary 병합 규칙을 적용하지 않으면 오류가 발생합니다.
    • 우선순위가 낮은 manifest에 더 낮은 targetSdkVersion 값이 있는 경우 병합 도구는 우선순위가 높은 manifest의 값을 사용하지만, 가져온 라이브러리가 계속해서 제대로 기능하는 데 필요한 시스템 권한도 추가합니다(예를 들어 더 높은 Android 버전에서 권한 제한이 증가된 경우). 이 동작에 관한 자세한 내용은 암시적 시스템 권한 관련 섹션을 참조하세요.
  • <intent-filter> 요소는 manifest 간에 결코 매칭되지 않습니다. 각 요소는 고유하게 취급되며 병합된 manifest에서 공통적인 상위 요소에 추가됩니다.

속성 간에 발생하는 다른 모든 충돌의 경우 오류를 수신합니다. 우선순위가 높은 manifest 파일에 특수한 속성을 추가하여 병합 도구에 오류 해결 방법을 지시해야 합니다(병합 규칙 마커에 관한 다음 섹션 참조).

속성 기본값을 사용하지 마세요. 모든 고유한 속성은 동일한 요소에 결합되므로 우선순위가 높은 manifest가 선언 없이 속성 기본값을 사용하면 예상치 못한 결과가 발생할 수 있습니다. 예를 들어 우선순위가 높은 manifest는 android:launchMode 속성을 선언하지 않는 경우 "standard"의 기본값을 사용합니다. 그러나 우선순위가 낮은 manifest가 다른 값으로 이 속성을 선언한다면 이 값이 병합된 manifest에 적용됩니다(기본값 재정의). 그러므로 각 속성을 원하는 대로 명시적으로 정의해야 합니다. (각 속성의 기본값은 manifest 참조에 기록됩니다.)

병합 규칙 마커

병합 규칙 마커는 병합 충돌 해결 방법에 관한 기본 설정을 표현하거나 원하지 않는 요소와 속성을 제거하는 데 사용할 수 있는 XML 속성입니다. 전체 요소에 마커를 적용하거나 요소의 특정 속성에만 마커를 적용할 수 있습니다.

두 개의 manifest 파일을 병합할 경우 병합 도구는 우선순위가 높은 manifest 파일에서 해당 마커를 검색합니다.

모든 마커는 Android tools 네임스페이스에 속하므로 먼저 다음과 같이 <manifest> 요소에서 이 네임스페이스를 선언해야 합니다.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.myapp"
        xmlns:tools="http://schemas.android.com/tools">
    

노드 마커

전체 XML 요소(특정 manifest 요소의 모든 속성 및 모든 하위 태그)에 병합 규칙을 적용하려면 다음 속성을 사용합니다.

tools:node="merge"
충돌이 없으면 병합 충돌 추론을 사용하여 이 태그의 모든 속성과 모든 중첩된 요소를 병합합니다. 이것은 요소의 기본 동작입니다.

우선순위가 낮은 manifest:

    <activity 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>
    

우선순위가 높은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:node="merge">
    </activity>
    

병합된 manifest 결과:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateUnchanged">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    
tools:node="merge-only-attributes"
이 태그의 속성만 병합하고 중첩된 요소는 병합하지 않습니다.

우선순위가 낮은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:windowSoftInputMode="stateUnchanged">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <data android:type="image/*" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>
    

우선순위가 높은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:node="merge-only-attributes">
    </activity>
    

병합된 manifest 결과:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateUnchanged">
    </activity>
    
tools:node="remove"
병합된 manifest에서 이 요소를 제거합니다. 이 요소를 삭제하기만 하면 될 것 같지만, 병합된 manifest에서 필요 없는 요소를 발견했는데 제어할 수 없는 우선순위가 낮은 manifest 파일에 의해 제공된 요소라면(예: 가져온 라이브러리) 이 방법을 사용해야 합니다.

우선순위가 낮은 manifest:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="cow"
          android:value="@string/moo"/>
      <meta-data android:name="duck"
          android:value="@string/quack"/>
    </activity-alias>
    

우선순위가 높은 manifest:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="cow"
          tools:node="remove"/>
    </activity-alias>
    

병합된 manifest 결과:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="duck"
          android:value="@string/quack"/>
    </activity-alias>
    
tools:node="removeAll"
tools:node="remove"와 비슷하지만 동일한 상위 요소 내에서 이 요소 유형과 일치하는 모든 요소를 제거합니다.

우선순위가 낮은 manifest:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="cow"
          android:value="@string/moo"/>
      <meta-data android:name="duck"
          android:value="@string/quack"/>
    </activity-alias>
    

우선순위가 높은 manifest:

    <activity-alias android:name="com.example.alias">
      <meta-data tools:node="removeAll"/>
    </activity-alias>
    

병합된 manifest 결과:

    <activity-alias android:name="com.example.alias">
    </activity-alias>
    
tools:node="replace"
우선순위가 낮은 요소를 완전히 대체합니다. 즉, 우선순위가 낮은 manifest에 일치하는 요소가 있으면 이를 무시하고 이 manifest에 나타난 것과 똑같이 이 요소를 사용합니다.

우선순위가 낮은 manifest:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="cow"
          android:value="@string/moo"/>
      <meta-data android:name="duck"
          android:value="@string/quack"/>
    </activity-alias>
    

우선순위가 높은 manifest:

    <activity-alias android:name="com.example.alias"
        tools:node="replace">
      <meta-data android:name="fox"
          android:value="@string/dingeringeding"/>
    </activity-alias>
    

병합된 manifest 결과:

    <activity-alias android:name="com.example.alias">
      <meta-data android:name="fox"
          android:value="@string/dingeringeding"/>
    </activity-alias>
    
tools:node="strict"
우선순위가 낮은 manifest에서 이 요소가 우선순위가 높은 manifest의 요소와 정확히 일치하지 않을 때마다 빌드 실패를 생성합니다(다른 병합 규칙 마커에 의해 해결되는 경우 제외). 이는 병합 충돌 추론을 재정의합니다. 예를 들어 우선순위가 낮은 manifest에 단순히 추가 속성을 포함하면 빌드가 실패합니다(반면 기본 동작에서는 병합된 manifest에 추가 속성을 추가함).

우선순위가 낮은 manifest:

    <activity 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>
    

우선순위가 높은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:node="strict">
    </activity>
    

manifest 병합 오류가 생성됩니다. strict 모드에서는 두 개의 manifest 요소가 다를 수 없습니다. 따라서 이 차이를 해결하기 위해 다른 병합 규칙 마커를 적용해야 합니다. (일반적으로 이 두 요소는 tools:node="merge"에 관한 위의 예제에 나와 있듯이 정상적으로 병합됩니다.)

속성 마커

manifest 태그의 특정 속성에만 병합 규칙을 적용하려면 다음 속성을 사용합니다. 각 속성은 쉼표로 구분한 하나 이상의 속성 이름(속성 네임스페이스 포함)을 허용합니다.

tools:remove="attr, ..."
병합된 manifest에서 지정된 속성을 삭제합니다. 이러한 속성을 삭제하기만 하면 될 것 같지만, 우선순위가 낮은 manifest 파일에 포함된 이러한 속성을 병합된 manifest에 포함하지 않으려면 이 방법을 사용해야 합니다.

우선순위가 낮은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:windowSoftInputMode="stateUnchanged">
    

우선순위가 높은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:remove="android:windowSoftInputMode">
    

병합된 manifest 결과:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait">
    
tools:replace="attr, ..."
우선순위가 낮은 manifest의 지정된 속성을 이 manifest의 속성과 교체합니다. 다시 말해, 우선순위가 높은 manifest의 값을 항상 유지합니다.

우선순위가 낮은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:theme="@oldtheme"
        android:exported="false"
        android:windowSoftInputMode="stateUnchanged">
    

우선순위가 높은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:theme="@newtheme"
        android:exported="true"
        android:screenOrientation="portrait"
        tools:replace="android:theme,android:exported">
    

병합된 manifest 결과:

    <activity android:name="com.example.ActivityOne"
        android:theme="@newtheme"
        android:exported="true"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="stateUnchanged">
    
tools:strict="attr, ..."
우선순위가 낮은 manifest의 이 속성이 우선순위가 높은 manifest의 속성과 정확히 일치하지 않을 때마다 빌드 실패를 생성합니다. 병합 충돌 추론에 설명된 특수 동작이 있는 경우를 제외하고, 이것이 모든 속성의 기본 동작입니다.

우선순위가 낮은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="landscape">
    </activity>
    

우선순위가 높은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:screenOrientation="portrait"
        tools:strict="android:screenOrientation">
    </activity>
    

manifest 병합 오류가 생성됩니다. 충돌을 해결하기 위해 다른 병합 규칙 마커를 적용해야 합니다. (이는 기본 동작이므로 tools:strict="screenOrientation"을 제거한다면 위의 예제와 결과가 같습니다.)

다음과 같이 하나의 요소에 여러 개의 마커를 적용할 수 있습니다.

우선순위가 낮은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:theme="@oldtheme"
        android:exported="false"
        android:allowTaskReparenting="true"
        android:windowSoftInputMode="stateUnchanged">
    

우선순위가 높은 manifest:

    <activity android:name="com.example.ActivityOne"
        android:theme="@newtheme"
        android:exported="true"
        android:screenOrientation="portrait"
        tools:replace="android:theme,android:exported"
        tools:remove="android:windowSoftInputMode">
    

병합된 manifest 결과:

    <activity android:name="com.example.ActivityOne"
        android:theme="@newtheme"
        android:exported="true"
        android:allowTaskReparenting="true"
        android:screenOrientation="portrait">
    

마커 선택기

가져온 특정 라이브러리에만 병합 규칙 마커를 적용하고 싶다면 라이브러리 패키지 이름으로 tools:selector 속성을 추가합니다.

예를 들어 다음 manifest는 com.example.lib1 라이브러리의 우선순위가 낮은 manifest 파일에만 remove 병합 규칙을 적용합니다.

    <permission android:name="permissionOne"
        tools:node="remove"
        tools:selector="com.example.lib1">
    

다른 소스의 우선순위가 낮은 manifest라면 remove 병합 규칙을 무시합니다.

참고: 속성 마커와 함께 병합 규칙을 사용할 경우 마커에서 지정된 모든 속성에 병합 규칙이 적용됩니다.

가져온 라이브러리에서 <uses-sdk> 재정의

기본적으로 기본 manifest 파일보다 minSdkVersion 값이 라이브러리를 가져오면 오류가 발생하고, 라이브러리를 가져올 수 없습니다. 병합 도구가 이 충돌을 무시하고 앱의 낮은 minSdkVersion 값을 그대로 둔 채 라이브러리를 가져오게 하려면 overrideLibrary 속성을 <uses-sdk> 태그에 추가합니다. 속성 값은 하나 이상의 라이브러리 패키지 이름(쉼표로 구분)이 될 수 있는데, 이는 기본 manifest의 minSdkVersion을 재정의할 수 있는 라이브러리를 나타냅니다.

예를 들어 앱의 기본 manifest는 다음과 같이 overrideLibrary를 적용합니다.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.app"
              xmlns:tools="http://schemas.android.com/tools">
      <uses-sdk tools:overrideLibrary="com.example.lib1, com.example.lib2"/>
    ...
    

그 후에는 <uses-sdk> 태그와 관련된 오류 없이 다음 manifest를 병합할 수 있습니다. 병합된 manifest는 앱 manifest의 minSdkVersion="2"를 그대로 유지합니다.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.lib1">
       <uses-sdk android:minSdkVersion="4" />
    ...
    

암시적 시스템 권한

앱에서 자유롭게 액세스할 수 있었던 일부 Android API는 최신 Android 버전에서 시스템 권한으로 제한되었습니다. 이러한 API 액세스를 기대하는 앱이 작동 중단되지 않도록, 최신 Android 버전에서는 앱에서 targetSdkVersion이 제한을 추가한 버전보다 낮은 값으로 설정된 경우 권한 없이 해당 API에 계속 액세스할 수 있습니다. 이 동작은 API에 액세스할 수 있는 암시적 권한을 앱에 효과적으로 부여합니다. 따라서 targetSdkVersion의 값이 서로 다른 병합된 manifest에 다음과 같이 영향을 줄 수 있습니다.

우선순위가 낮은 manifest 파일에서 암시적 권한을 제공하는 targetSdkVersion의 값이 낮고 우선순위가 높은 manifest에 동일한 암시적 권한이 없을 경우(targetSdkVersion이 제한이 추가된 버전 이상일 경우) 병합 도구는 병합된 manifest에 명시적으로 시스템 권한을 추가합니다.

예를 들어, 앱에서 targetSdkVersion이 4 이상으로 설정되었는데 targetSdkVersion이 3 이하로 설정된 라이브러리를 가져오면, 병합 도구는 병합된 manifest에 WRITE_EXTERNAL_STORAGE 권한을 추가합니다. 표 2에는 병합된 manifest에 추가할 수 있는 모든 권한이 나열되어 있습니다.

표 2. 통합 도구가 병합된 manifest에 추가할 수 있는 권한 목록

우선순위가 낮은 manifest 선언 병합된 manifest에 추가되는 권한
targetSdkVersion이 3 이하임 WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE
targetSdkVersion이 15 이하이고 READ_CONTACTS를 사용함 READ_CALL_LOG
targetSdkVersion이 15 이하이고 WRITE_CONTACTS를 사용함 WRITE_CALL_LOG

병합된 manifest 검사 및 충돌 찾기

APK를 빌드하기 전이라도 Android 스튜디오에서 AndroidManifest.xml 파일을 열고 편집기 아래의 Merged Manifest 탭을 클릭하면 병합된 manifest를 미리 볼 수 있습니다.

병합된 manifest 뷰는 그림 2와 같이, 왼쪽에는 병합된 manifest 결과를 표시하고 오른쪽에는 병합된 각 manifest 파일 관련 정보를 표시합니다. 우선순위가 낮은 manifest 파일에서 병합된 요소는 왼쪽에서 다른 색상으로 강조표시됩니다. 각 색상의 키는 오른쪽의 Manifest Sources에서 지정됩니다.

그림 2. 병합된 manifest 뷰

빌드의 일부이지만 요소 또는 속성에 영향을 미치지 않은 manifest 파일은 오른쪽의 Other Manifest Files에 나열됩니다.

요소의 원래 위치에 관한 정보를 확인하려면 왼쪽에서 요소를 클릭합니다. 오른쪽의 Merging Log에 상세 정보가 나타납니다.

충돌이 발생하면 오른쪽의 Merging Errors 아래에 표시되며, 병합 규칙 마커를 사용하여 충돌을 해결하는 방법에 관한 권장 사항도 함께 표시됩니다. Event Log 창(View > Tool Windows > Event Log 선택)에도 오류가 표시됩니다.

병합 결정 트리의 전체 로그를 확인하려면 모듈의 build/outputs/logs/ 디렉터리에 있는 manifest-merger-buildVariant-report.txt라는 로그 파일을 참조하세요.

부록: 병합 정책

manifest 병합 도구는 어떤 manifest 파일의 모든 XML 요소를 다른 파일의 해당 요소와 논리적으로 매칭할 수 있습니다. 병합기는 '매칭 키'를 사용하여 각 요소를 매칭합니다. 고유한 속성 값(예: android:name) 또는 태그 자체의 자연적인 고유성(예: <supports-screen> 요소가 하나만 있을 수 있음)을 이용합니다. 두 개의 manifest에 동일한 XML 요소가 있는 경우 도구가 세 개의 병합 정책 중 하나를 사용하여 두 요소를 병합합니다.

병합
충돌하지 않는 모든 속성을 같은 태그로 결합하고 각각의 병합 정책에 따라 하위 요소를 병합합니다. 서로 충돌하는 속성이 있으면 병합 규칙 마커로 병합합니다.
하위 요소만 병합
속성을 결합하거나 병합하지 않고(우선순위가 가장 높은 manifest 파일이 제공한 속성만 유지) 병합 정책에 따라 하위 요소만 병합합니다.
유지
요소를 '그대로' 두고 병합된 파일의 공통 상위 요소에 추가합니다. 같은 요소에 관해 여러 개의 선언이 존재할 수 있을 경우에만 사용합니다.

표 3은 각 요소 유형, 사용한 병합 정책 유형, 두 manifest에서 요소 매칭을 판별하는 데 사용되는 키를 보여줍니다.

표 3. manifest 요소 병합 정책 및 매칭 키

요소 병합 정책 매칭 키
<action> 병합 android:name 속성
<activity> 병합 android:name 속성
<application> 병합 <manifest>당 하나만 있음
<category> 병합 android:name 속성
<data> 병합 <intent-filter>당 하나만 있음
<grant-uri-permission> 병합 <provider>당 하나만 있음
<instrumentation> 병합 android:name 속성
<intent-filter> 유지 매칭 없음. 상위 요소 내에서 여러 선언이 허용됨
<manifest> 하위 요소만 병합 파일 당 하나만 있음
<meta-data> 병합 android:name 속성
<path-permission> 병합 <provider>당 하나만 있음
<permission-group> 병합 android:name 속성
<permission> 병합 android:name 속성
<permission-tree> 병합 android:name 속성
<provider> 병합 android:name 속성
<receiver> 병합 android:name 속성
<screen> 병합 android:screenSize 속성
<service> 병합 android:name 속성
<supports-gl-texture> 병합 android:name 속성
<supports-screen> 병합 <manifest>당 하나만 있음
<uses-configuration> 병합 <manifest>당 하나만 있음
<uses-feature> 병합 android:name 속성(없는 경우 android:glEsVersion 속성)
<uses-library> 병합 android:name 속성
<uses-permission> 병합 android:name 속성
<uses-sdk> 병합 <manifest>당 하나만 있음
맞춤 요소 병합 매칭 없음. 병합 도구에 알려지지 않았으므로 항상 병합된 manifest에 포함됨