Manifestdateien verwalten

Auf dieser Seite wird beschrieben, wie Manifeste zusammengeführt werden und wie Sie Zusammenführungseinstellungen anwenden können, um Zusammenführungskonflikte zu beheben. Eine Einführung in die App-Manifestdatei finden Sie in der Übersicht über das App-Manifest.

Mehrere Manifestdateien zusammenführen

Deine APK- oder Android App Bundle-Datei kann nur eine AndroidManifest.xml-Datei enthalten, dein Android Studio-Projekt kann jedoch mehrere Manifestdateien enthalten, die vom Hauptquellsatz, Build-Varianten und importierten Bibliotheken bereitgestellt werden. Beim Erstellen Ihrer App führt der Gradle-Build alle Manifestdateien in einer Manifestdatei zusammen, die in Ihrer App verpackt ist.

Das Tool für die Manifestzusammenführung kombiniert alle XML-Elemente aus jeder Datei. Dabei werden die Zusammenführungsheuristiken und die Zusammenführungseinstellungen berücksichtigt, die Sie mit speziellen XML-Attributen definiert haben.

Tipp:Verwenden Sie die im folgenden Abschnitt beschriebene Ansicht Zusammengeführtes Manifest, um eine Vorschau der Ergebnisse des zusammengeführten Manifests anzuzeigen und Konfliktfehler zu finden.

Prioritäten zusammenführen

Das Zusammenführungstool führt alle Manifestdateien nacheinander in einer Datei zusammen, die sich nach der Priorität der einzelnen Manifestdateien richtet. Wenn Sie beispielsweise drei Manifestdateien haben, wird das Manifest mit der niedrigsten Priorität mit dem Manifest mit der nächsthöheren Priorität und anschließend mit dem Manifest mit der höchsten Priorität zusammengeführt, wie in Abbildung 1 dargestellt.

Abbildung 1: Der Vorgang zum Zusammenführen von drei Manifestdateien, von der niedrigsten zur höchsten Priorität.

Es gibt drei grundlegende Typen von Manifestdateien, die ineinander zusammengeführt werden können, und deren Zusammenführungsprioritäten sind wie folgt (höchste Priorität zuerst):

  1. Manifestdatei für Ihre Build-Variante

    Wenn Sie mehrere Quellsätze für Ihre Variante haben, lauten ihre Manifestprioritäten:

    • Build-Variantenmanifest (z. B. src/demoDebug/)
    • Manifest des Build-Typs (z. B. src/debug/)
    • Manifest für Produktvarianten (z. B. src/demo/)

      Wenn Sie Flavor-Dimensionen verwenden, entsprechen die Manifestprioritäten der Reihenfolge, in der die einzelnen Dimensionen in der Eigenschaft flavorDimensions aufgeführt sind (die erste ist die höchste Priorität).

  2. Haupt-Manifestdatei für das App-Modul
  3. Manifestdatei aus einer enthaltenen Bibliothek

    Wenn Sie mehrere Bibliotheken haben, entsprechen die Manifestprioritäten der Reihenfolge, in der sie in Ihrem Gradle-Block dependencies angezeigt werden.

Beispielsweise wird ein Manifest einer Bibliothek mit dem Hauptmanifest und dann das Hauptmanifest im Manifest der Build-Variante zusammengeführt. Dies sind für alle Quellsätze dieselben Zusammenführungsprioritäten, wie unter Mit Quellsätzen erstellen beschrieben.

Wichtig:Build-Konfigurationen aus der Datei build.gradle überschreiben alle entsprechenden Attribute in der zusammengeführten Manifestdatei. Beispielsweise überschreibt das minSdk-Element aus der Datei build.gradle oder build.gradle.kts das übereinstimmende Attribut im Manifestelement <uses-sdk>. Um Verwechslungen zu vermeiden, lassen Sie das <uses-sdk>-Element weg und definieren diese Attribute nur in der Datei build.gradle. Weitere Informationen finden Sie unter Build konfigurieren.

Konfliktheuristiken zusammenführen

Das Zusammenführungstool kann jedes XML-Element in einem Manifest logisch mit einem entsprechenden Element in einem anderen Manifest abgleichen. Weitere Informationen zur Funktionsweise des Abgleichs finden Sie unter Prioritäten zusammenführen im vorherigen Abschnitt.

Wenn ein Element aus dem Manifest mit niedrigerer Priorität mit keinem Element im Manifest mit höherer Priorität übereinstimmt, wird es dem zusammengeführten Manifest hinzugefügt. Wenn jedoch ein übereinstimmendes Element vorhanden ist, versucht das Zusammenführungstool, alle Attribute jedes Elements im selben Element zu kombinieren. Wenn das Tool feststellt, dass beide Manifeste dasselbe Attribut mit unterschiedlichen Werten enthalten, tritt ein Zusammenführungskonflikt auf.

In Tabelle 1 sind die möglichen Ergebnisse dargestellt, wenn das Zusammenführungstool versucht, alle Attribute im selben Element zu kombinieren.

Tabelle 1 Standardverhalten bei der Zusammenführung von Attributwerten

Attribut mit hoher Priorität Attribut mit niedriger Priorität Zusammengeführtes Ergebnis des Attributs
Gar keinen Mehrwert Gar keinen Mehrwert Kein Wert (Standardwert verwenden)
Wert B Wert B
Wert A Gar keinen Mehrwert Wert A
Wert A Wert A
Wert B Konfliktfehler: Sie müssen eine Markierung für Zusammenführungsregeln hinzufügen.

Es gibt jedoch einige Situationen, in denen das Zusammenführungstool anders verhält, um Zusammenführungskonflikte zu vermeiden:

  • Attribute im Element <manifest> werden niemals zusammengeführt. Es werden nur die Attribute aus dem Manifest mit der höchsten Priorität verwendet.
  • Das Attribut android:required in den Elementen <uses-feature> und <uses-library> verwendet eine ODER-Zusammenführung. Bei einem Konflikt wird "true" angewendet und das von einem Manifest benötigte Feature oder der Bibliothek ist immer enthalten.
  • Für Attribute im Element <uses-sdk> wird immer der Wert aus dem Manifest mit höherer Priorität verwendet, außer in den folgenden Situationen:
    • Wenn das Manifest mit niedrigerer Priorität einen höheren minSdk-Wert hat, tritt ein Fehler auf, sofern Sie nicht die Zusammenführungsregel overrideLibrary anwenden.
    • Wenn das Manifest mit niedrigerer Priorität einen niedrigeren Wert für targetSdkVersion hat, verwendet das Zusammenführungstool den Wert aus dem Manifest mit der höheren Priorität. Außerdem werden alle Systemberechtigungen hinzugefügt, die erforderlich sind, damit die importierte Bibliothek weiterhin ordnungsgemäß funktioniert. Dies ist der Fall, wenn für die höhere Android-Version die Berechtigungseinschränkungen erhöht wurden. Weitere Informationen zu diesem Verhalten finden Sie im Abschnitt zu impliziten Systemberechtigungen.
  • Das <intent-filter>-Element stimmt nie mit den Manifesten überein. Jedes Element wird als eindeutig behandelt und dem gemeinsamen übergeordneten Element im zusammengeführten Manifest hinzugefügt.

Bei allen anderen Konflikten zwischen Attributen wird eine Fehlermeldung angezeigt und Sie müssen das Zusammenführungstool anweisen, wie er gelöst werden kann, indem Sie der Manifestdatei mit höherer Priorität ein spezielles Attribut hinzufügen. Weitere Informationen finden Sie im folgenden Abschnitt zu Markierungen für Zusammenführungsregeln.

Machen Sie sich nicht von Standardattributwerten abhängig. Da alle eindeutigen Attribute im selben Element kombiniert werden, kann dies zu unerwarteten Ergebnissen führen, wenn das Manifest mit höherer Priorität tatsächlich vom Standardwert eines Attributs abhängt, es aber nicht deklariert wird. Wenn das Manifest mit höherer Priorität beispielsweise nicht das Attribut android:launchMode deklariert, wird der Standardwert "standard" verwendet. Wenn das Manifest mit niedrigerer Priorität dieses Attribut jedoch mit einem anderen Wert deklariert, wird dieser Wert auf das zusammengeführte Manifest angewendet, wodurch der Standardwert überschrieben wird. Sie sollten jedes Attribut explizit wie gewünscht definieren. Standardwerte für jedes Attribut sind in der Manifestreferenz dokumentiert.

Markierungen für Regeln zusammenführen

Eine Markierung für Zusammenführungsregeln ist ein XML-Attribut, mit dem Sie angeben können, wie Sie Zusammenführungskonflikte lösen oder unerwünschte Elemente und Attribute entfernen möchten. Sie können eine Markierung entweder auf ein ganzes Element oder nur auf bestimmte Attribute in einem Element anwenden.

Beim Zusammenführen von zwei Manifestdateien sucht das Zusammenführungstool in der Manifestdatei mit höherer Priorität nach diesen Markierungen.

Alle Markierungen gehören zum Android-Namespace tools. Daher muss dieser Namespace zuerst wie hier gezeigt im <manifest>-Element deklariert werden:

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

Knotenmarkierungen

Wenn Sie eine Zusammenführungsregel auf ein ganzes XML-Element (auf alle Attribute in einem bestimmten Manifestelement und auf alle untergeordneten Tags) anwenden möchten, verwenden Sie die folgenden Attribute:

tools:node="merge"
Führen Sie alle Attribute in diesem Tag und alle verschachtelten Elemente mithilfe der Konfliktheuristik zusammen, wenn keine Konflikte auftreten. Das ist das Standardverhalten für Elemente.

Manifest mit niedriger Priorität:

<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 mit hoher Priorität:

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

Ergebnis des zusammengeführten Manifests:

<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"
Führen Sie nur die Attribute in diesem Tag zusammen, keine verschachtelten Elemente.

Manifest mit niedriger Priorität:

<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 mit hoher Priorität:

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

Ergebnis des zusammengeführten Manifests:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
</activity>
tools:node="remove"
Entfernen Sie dieses Element aus dem zusammengeführten Manifest. Wird verwendet, wenn Sie in Ihrem zusammengeführten Manifest ein Element finden, das nicht von einer Manifestdatei mit niedrigerer Priorität bereitgestellt wird, die außerhalb Ihrer Kontrolle liegt (z. B. eine importierte Bibliothek).

Manifest mit niedriger Priorität:

<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 mit hoher Priorität:

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

Ergebnis des zusammengeführten Manifests:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="duck"
      android:value="@string/quack"/>
</activity-alias>
tools:node="removeAll"
Ähnlich wie tools:node="remove", entfernt jedoch alle Elemente, die diesem Elementtyp entsprechen (im selben übergeordneten Element).

Manifest mit niedriger Priorität:

<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 mit hoher Priorität:

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

Ergebnis des zusammengeführten Manifests:

<activity-alias android:name="com.example.alias">
</activity-alias>
tools:node="replace"
Ersetzen Sie das Element mit der niedrigeren Priorität vollständig. Wenn also ein übereinstimmendes Element im Manifest mit niedrigerer Priorität vorhanden ist, ignorieren Sie es und verwenden Sie dieses Element genau so, wie es in diesem Manifest angezeigt wird.

Manifest mit niedriger Priorität:

<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 mit hoher Priorität:

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

Ergebnis des zusammengeführten Manifests:

<activity-alias android:name="com.example.alias">
  <meta-data android:name="fox"
      android:value="@string/dingeringeding"/>
</activity-alias>
tools:node="strict"
Ein Build-Fehler wird immer dann generiert, wenn dieses Element im Manifest mit niedrigerer Priorität nicht genau mit dem Element im Manifest mit höherer Priorität übereinstimmt – es sei denn, dies lässt sich durch andere Markierungen für Zusammenführungsregeln beheben. Dadurch wird die Heuristik für Zusammenführungskonflikte überschrieben. Wenn beispielsweise das Manifest mit niedrigerer Priorität ein zusätzliches Attribut enthält, schlägt der Build fehl. Im Standardverhalten wird das zusätzliche Attribut dem zusammengeführten Manifest hinzugefügt.

Manifest mit niedriger Priorität:

<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 mit hoher Priorität:

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

Dadurch wird ein Fehler bei der Zusammenführung der Manifeste verursacht. Die beiden Manifestelemente dürfen sich im strikten Modus nicht unterscheiden. Sie müssen andere Markierungen für Zusammenführungsregeln anwenden, um diese Unterschiede zu beheben. Ohne tools:node="strict" können diese beiden Dateien fehlerfrei zusammengeführt werden, wie im Beispiel für tools:node="merge" gezeigt.

Attributmarkierungen

Wenn Sie eine Zusammenführungsregel nur auf bestimmte Attribute in einem Manifest-Tag anwenden möchten, verwenden Sie die folgenden Attribute. Jedes Attribut akzeptiert einen oder mehrere, durch Kommas getrennte Attributnamen (einschließlich des Attribut-Namespace).

tools:remove="attr, ..."
Die angegebenen Attribute aus dem zusammengeführten Manifest entfernen. Wird verwendet, wenn die Manifestdatei mit niedrigerer Priorität diese Attribute enthält und Sie dafür sorgen möchten, dass sie nicht in das zusammengeführte Manifest aufgenommen werden.

Manifest mit niedriger Priorität:

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

Manifest mit hoher Priorität:

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

Ergebnis des zusammengeführten Manifests:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait">
tools:replace="attr, ..."
Ersetzen Sie die angegebenen Attribute im Manifest mit niedrigerer Priorität durch die Attribute aus diesem Manifest. Mit anderen Worten: Behalten Sie immer die Werte des Manifests mit höherer Priorität bei.

Manifest mit niedriger Priorität:

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

Manifest mit hoher Priorität:

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

Ergebnis des zusammengeführten Manifests:

<activity android:name="com.example.ActivityOne"
    android:theme="@newtheme"
    android:exported="true"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
tools:strict="attr, ..."
Wenn diese Attribute im Manifest mit niedrigerer Priorität nicht genau mit den Attributen im Manifest mit der höheren Priorität übereinstimmen, wird ein Build-Fehler generiert. Das ist das Standardverhalten für alle Attribute, mit Ausnahme der Attribute mit einem speziellen Verhalten, das unter Konfliktheuristiken zusammenführen beschrieben wird.

Manifest mit niedriger Priorität:

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

Manifest mit hoher Priorität:

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

Dadurch wird ein Fehler bei der Zusammenführung der Manifeste verursacht. Sie müssen andere Markierungen für Zusammenführungsregeln anwenden, um den Konflikt zu beheben. Das ist das Standardverhalten, sodass dasselbe Ergebnis auftritt, wenn tools:strict="screenOrientation" explizit hinzugefügt wird.

Sie können auch mehrere Markierungen auf ein Element anwenden, wie im folgenden Beispiel gezeigt:

Manifest mit niedriger Priorität:

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

Manifest mit hoher Priorität:

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

Ergebnis des zusammengeführten Manifests:

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

Markierungsauswahl

Wenn Sie die Markierungen der Zusammenführungsregel nur auf eine bestimmte importierte Bibliothek anwenden möchten, fügen Sie das Attribut tools:selector mit dem Paketnamen der Bibliothek hinzu.

Mit dem folgenden Manifest wird beispielsweise die Zusammenführungsregel remove nur angewendet, wenn die Manifestdatei mit niedrigerer Priorität aus der Bibliothek com.example.lib1 stammt:

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

Wenn das Manifest mit niedrigerer Priorität aus einer anderen Quelle stammt, wird die Zusammenführungsregel remove ignoriert.

Hinweis:Wenn Sie dieses Attribut zusammen mit einer der Attributmarkierungen verwenden, gilt es für alle in der Markierung angegebenen Attribute.

<uses-sdk> für importierte Bibliotheken überschreiben

Beim Importieren einer Bibliothek mit einem minSdk-Wert, der höher als in der Hauptmanifestdatei ist, tritt standardmäßig ein Fehler auf und die Bibliothek kann nicht importiert werden.

Damit das Zusammenführungstool diesen Konflikt ignoriert und die Bibliothek importiert, aber den niedrigeren minSdk-Wert der App behält, fügen Sie dem <uses-sdk>-Tag das Attribut overrideLibrary hinzu. Der Attributwert kann ein oder mehrere Bibliothekspaketnamen (durch Kommas getrennt) sein, die die Bibliotheken angeben, die die minSdk des Hauptmanifests überschreiben können.

Beispiel: overrideLibrary wird vom Hauptmanifest Ihrer App so angewandt:

<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"/>
...

Anschließend kann das folgende Manifest ohne Fehler in Bezug auf das <uses-sdk>-Tag zusammengeführt werden und das zusammengeführte Manifest behält minSdk="2" aus dem App-Manifest.

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

Implizite Systemberechtigungen

Einige Android APIs, die früher kostenlos von Apps genutzt werden konnten, sind in aktuellen Android-Versionen durch Systemberechtigungen eingeschränkt.

Damit Apps, die Zugriff auf diese APIs erwarten, nicht funktionieren, können Apps in den aktuellen Versionen von Android weiterhin ohne die Berechtigung auf diese APIs zugreifen, wenn targetSdkVersion auf einen Wert festgelegt ist, der niedriger als die Version ist, in der die Einschränkung hinzugefügt wurde. Dadurch erhält die App eine implizite Berechtigung, um Zugriff auf die APIs zu gewähren. Die zusammengeführten Manifeste, die unterschiedliche Werte für targetSdkVersion haben, können betroffen sein.

Wenn die Manifestdatei mit niedrigerer Priorität einen niedrigeren Wert für targetSdkVersion hat, der ihr eine implizite Berechtigung gewährt, und das Manifest mit höherer Priorität nicht dieselbe implizite Berechtigung hat (weil seine targetSdkVersion gleich oder höher ist als die Version, in der die Einschränkung hinzugefügt wurde), fügt das Zusammenführungstool die Systemberechtigung explizit dem zusammengeführten Manifest hinzu.

Wenn in Ihrer App beispielsweise targetSdkVersion auf 4 oder höher festgelegt und eine Bibliothek importiert wird, in der targetSdkVersion auf 3 oder niedriger festgelegt ist, fügt das Zusammenführungstool die Berechtigung WRITE_EXTERNAL_STORAGE dem zusammengeführten Manifest hinzu.

In Tabelle 2 sind alle möglichen Berechtigungen aufgeführt, die dem zusammengeführten Manifest hinzugefügt werden können:

Tabelle 2 Liste der Berechtigungen, die das Merger-Tool zum zusammengeführten Manifest hinzufügen könnte

Deklarationen von Manifesten mit niedrigerer Priorität Berechtigungen, die dem zusammengeführten Manifest hinzugefügt wurden
targetSdkVersion ist 3 oder niedriger WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE
targetSdkVersion ist 15 oder niedriger und verwendet READ_CONTACTS READ_CALL_LOG
targetSdkVersion ist 15 oder niedriger und verwendet WRITE_CONTACTS WRITE_CALL_LOG

Zusammengeführtes Manifest prüfen und Konflikte finden

Schon vor dem Erstellen der App können Sie sich in einer Vorschau ansehen, wie das zusammengeführte Manifest aussieht. So rufen Sie eine Vorschau auf:

  1. Öffnen Sie in Android Studio die Datei AndroidManifest.xml.
  2. Klicken Sie unten im Editor auf den Tab Zusammengeführtes Manifest.

Die Ansicht „Zusammengeführtes Manifest“ zeigt links die Ergebnisse des zusammengeführten Manifests und rechts Informationen zu jeder zusammengeführten Manifestdatei (siehe Abbildung 2).

Die Elemente, die aus Manifestdateien mit niedrigerer Priorität zusammengeführt wurden, werden links farblich hervorgehoben. Der Schlüssel für die einzelnen Farben wird unter Manifest-Quellen angegeben.

Abbildung 2: Die Ansicht „Zusammengeführtes Manifest“.

Manifestdateien, die Teil des Builds waren, aber keine Elemente oder Attribute eingereicht haben, sind unter Andere Manifestdateien aufgeführt.

Wenn Sie Informationen zur Quelle eines Elements sehen möchten, klicken Sie im linken Bereich darauf. Die Details werden dann unter Log zusammenführen angezeigt.

Wenn Konflikte auftreten, werden sie unter Zusammenführen von Fehlern aufgeführt. Dort wird auch eine Empfehlung zum Beheben des Konflikts mithilfe von Markierungen für Zusammenführungsregeln angezeigt.

Die Fehler werden auch im Fenster Ereignisprotokoll angezeigt. Um sie anzusehen, wählen Sie Ansicht > Toolfenster > Ereignisprotokoll aus.

Ein vollständiges Log des zusammengeführten Entscheidungsbaums finden Sie im build/outputs/logs/-Verzeichnis des Moduls mit dem Namen manifest-merger-buildVariant-report.txt.

Zusammenführungsrichtlinien

Das Tool für die Manifestzusammenführung kann jedes XML-Element aus einer Manifestdatei logisch mit einem entsprechenden Element in einer anderen Datei abgleichen. Bei der Zusammenführung wird jedes Element mithilfe eines Übereinstimmungsschlüssels abgeglichen. Dabei handelt es sich entweder um einen eindeutigen Attributwert (z. B. android:name) oder die natürliche Eindeutigkeit des Tags selbst (es kann beispielsweise nur ein <supports-screen>-Element vorhanden sein).

Wenn zwei Manifeste dasselbe XML-Element haben, führt das Tool die beiden Elemente mithilfe einer von drei Zusammenführungsrichtlinien zusammen:

Zusammenführen
Kombinieren Sie alle nicht in Konflikt stehenden Attribute im selben Tag und führen Sie untergeordnete Elemente gemäß der entsprechenden Zusammenführungsrichtlinie zusammen. Wenn Attribute miteinander in Konflikt stehen, führen Sie sie mit den Markierungen für Zusammenführungsregeln zusammen.
Nur untergeordnete Elemente zusammenführen
Kombinieren oder zusammenführen Sie die Attribute nicht (belassen Sie nur die Attribute der Manifestdatei mit der höchsten Priorität) und führen Sie untergeordnete Elemente nicht gemäß ihrer Zusammenführungsrichtlinie zusammen.
Notizen
Lassen Sie das Element unverändert und fügen Sie es dem gemeinsamen übergeordneten Element in der zusammengeführten Datei hinzu. Er wird nur verwendet, wenn mehrere Deklarationen für dasselbe Element zulässig sind.

In Tabelle 3 sind alle Elementtypen, der verwendete Typ der Zusammenführungsrichtlinie und der Schlüssel aufgeführt, mit dem eine Elementübereinstimmung zwischen zwei Manifesten ermittelt wird:

Tabelle 3 Zusammenführungsrichtlinien und Abgleichsschlüssel für Manifestelemente

Element Richtlinie für Zusammenführung Übereinstimmungsschlüssel
<action> Zusammenführen Attribut „android:name
<activity> Zusammenführen Attribut „android:name
<application> Zusammenführen Es gibt nur eine pro <manifest>.
<category> Zusammenführen Attribut „android:name
<data> Zusammenführen Es gibt nur eine pro <intent-filter>.
<grant-uri-permission> Zusammenführen Es gibt nur eine pro <provider>.
<instrumentation> Zusammenführen Attribut „android:name
<intent-filter> Notizen Keine Übereinstimmung. Mehrere Deklarationen innerhalb des übergeordneten Elements sind zulässig.
<manifest> Nur untergeordnete Elemente zusammenführen Es gibt nur eine pro Datei.
<meta-data> Zusammenführen Attribut „android:name
<path-permission> Zusammenführen Es gibt nur eine pro <provider>.
<permission-group> Zusammenführen Attribut „android:name
<permission> Zusammenführen Attribut „android:name
<permission-tree> Zusammenführen Attribut „android:name
<provider> Zusammenführen Attribut „android:name
<receiver> Zusammenführen Attribut „android:name
<screen> Zusammenführen Attribut „android:screenSize
<service> Zusammenführen Attribut „android:name
<supports-gl-texture> Zusammenführen Attribut „android:name
<supports-screen> Zusammenführen Es gibt nur eine pro <manifest>.
<uses-configuration> Zusammenführen Es gibt nur eine pro <manifest>.
<uses-feature> Zusammenführen Attribut android:name (falls nicht vorhanden, dann das Attribut android:glEsVersion)
<uses-library> Zusammenführen Attribut „android:name
<uses-permission> Zusammenführen Attribut „android:name
<uses-sdk> Zusammenführen Es gibt nur eine pro <manifest>.
Benutzerdefinierte Elemente Zusammenführen Keine Übereinstimmung. Diese sind dem Zusammenführungstool unbekannt und immer im zusammengeführten Manifest enthalten.

Build-Variablen in Manifest einfügen

Wenn Sie Variablen in Ihre AndroidManifest.xml-Datei einfügen müssen, die in der Datei build.gradle definiert sind, können Sie dies mit dem Attribut manifestPlaceholders tun. Dieses Attribut verwendet eine Zuordnung von Schlüssel/Wert-Paaren, wie hier dargestellt:

Groovig

android {
    defaultConfig {
        manifestPlaceholders = [hostName:"www.example.com"]
    }
    ...
}

Kotlin

android {
    defaultConfig {
        manifestPlaceholders["hostName"] = "www.example.com"
    }
    ...
}

Anschließend können Sie einen der Platzhalter in die Manifestdatei als Attributwert einfügen:

<intent-filter ... >
    <data android:scheme="https" android:host="${hostName}" ... />
    ...
</intent-filter>

Standardmäßig stellen die Build-Tools auch die Anwendungs-ID Ihrer App im Platzhalter ${applicationId} bereit. Der Wert entspricht immer der endgültigen Anwendungs-ID für den aktuellen Build, einschließlich Änderungen nach Build-Varianten. Dies ist nützlich, wenn Sie auch zwischen Ihren Build-Varianten einen eindeutigen Namespace für Kennungen wie eine Intent-Aktion verwenden möchten.

Wenn Ihre build.gradle-Datei beispielsweise so aussieht:

Groovig

android {
    defaultConfig {
        applicationId "com.example.myapp"
    }
    flavorDimensions "type"
    productFlavors {
        free {
            applicationIdSuffix ".free"
            dimension "type"
        }
        pro {
            applicationIdSuffix ".pro"
            dimension "type"
        }
    }
}

Kotlin

android {
    defaultConfig {
        applicationId = "com.example.myapp"
    }
    flavorDimensions += "type"
    productFlavors {
        create("free") {
            applicationIdSuffix = ".free"
            dimension = "type"
        }
        create("pro") {
            applicationIdSuffix = ".pro"
            dimension = "type"
        }
    }
}

Anschließend können Sie die Anwendungs-ID wie folgt in Ihr Manifest einfügen:

<intent-filter ... >
    <action android:name="${applicationId}.TRANSMOGRIFY" />
    ...
</intent-filter>

Das Manifestergebnis, wenn Sie die Geschmacksrichtung „free“ erstellen, lautet:

<intent-filter ... >
   <action android:name="com.example.myapp.free.TRANSMOGRIFY" />
    ...
</intent-filter>

Weitere Informationen finden Sie unter Anwendungs-ID festlegen.