Manifestdateien verwalten

Auf dieser Seite wird beschrieben, wie das Zusammenführen von Manifesten funktioniert und wie Sie Zusammenführungseinstellungen anwenden können, um Zusammenführungskonflikte zu beheben. Eine Einführung in die App-Manifestdatei finden Sie im Hilfeartikel App-Manifest – Übersicht.

Mehrere Manifestdateien zusammenführen

Ihre APK- oder Android App Bundle-Datei kann nur eine AndroidManifest.xml-Datei enthalten, Ihr Android Studio-Projekt kann jedoch mehrere Manifestdateien enthalten, die vom Haupt-Quellsatz, von Buildvarianten und von importierten Bibliotheken bereitgestellt werden. Beim Erstellen Ihrer App werden alle Manifestdateien vom Gradle-Build in einer einzigen Manifestdatei zusammengeführt, die in Ihre App verpackt wird.

Das Manifest-Merge-Tool kombiniert alle XML-Elemente aus jeder Datei, indem es Heuristiken für die Zusammenführung und die Zusammenführungseinstellungen befolgt, die Sie mit speziellen XML-Attributen definiert haben.

Tipp:In der Ansicht Merged Manifest (Zusammengeführtes Manifest), die im nächsten Abschnitt beschrieben wird, können Sie sich eine Vorschau der Ergebnisse des zusammengeführten Manifests ansehen und Konfliktfehler finden.

Prioritäten zusammenführen

Das Tool zur Zusammenführung kombiniert alle Manifestdateien nacheinander in einer Datei, basierend auf der Priorität der einzelnen Manifestdateien. Wenn Sie beispielsweise drei Manifestdateien haben, wird das Manifest mit der niedrigsten Priorität in das Manifest mit der nächsthöheren Priorität und dann in das Manifest mit der höchsten Priorität zusammengeführt, wie in Abbildung 1 dargestellt.

Abbildung 1. Das Zusammenführen von drei Manifestdateien, wobei die Datei mit der niedrigsten Priorität der Datei mit der höchsten Priorität vorangestellt wird.

Es gibt drei grundlegende Typen von Manifestdateien, die miteinander zusammengeführt werden können. Die Zusammenführungsprioritäten sind folgende (höchste Priorität zuerst):

  1. Manifestdatei für Ihre Buildvariante

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

    • Manifest der Build-Variante (z. B. src/demoDebug/)
    • Manifest für den Build-Typ (z. B. src/debug/)
    • Manifest der Produktvariante (z. B. src/demo/)

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

  2. Hauptmanifestdatei für das App-Modul
  3. Manifestdatei aus einer eingebundenen Bibliothek

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

Beispielsweise wird ein Bibliotheksmanifest in das Hauptmanifest und dann das Hauptmanifest in das Manifest der Buildvariante zusammengeführt. Hinweis: Dies sind dieselben Zusammenführungsprioritäten für alle Quellsätze, 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 wird das übereinstimmende Attribut im Manifest-Element <uses-sdk> durch das minSdk aus der Datei build.gradle oder build.gradle.kts überschrieben. Um Verwirrung zu vermeiden, lassen Sie das Element <uses-sdk> weg und definieren Sie diese Properties nur in der Datei build.gradle. Weitere Informationen finden Sie unter Build konfigurieren.

Heuristiken für Zusammenführungskonflikte

Das Tool zum Zusammenführen kann jedes XML-Element aus einem Manifest logisch mit einem entsprechenden Element in einem anderen Manifest abgleichen. Weitere Informationen zur Funktionsweise des Abgleichs finden Sie im Abschnitt Zusammenführungsprioritäten 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 Tool, alle Attribute aus den einzelnen Elementen in dasselbe Element zu kombinieren. Wenn das Tool feststellt, dass beide Manifeste dasselbe Attribut mit unterschiedlichen Werten enthalten, tritt ein Konflikt beim Zusammenführen auf.

In Tabelle 1 sind die möglichen Ergebnisse dargestellt, wenn das Tool zum Zusammenführen versucht, alle Attribute in dasselbe Element zu kombinieren.

Tabelle 1 Standardzusammenführungsverhalten für Attributwerte

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 die Zusammenführungsregel hinzufügen.

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

  • Attribute im <manifest>-Element werden nie zusammengeführt. Es werden nur die Attribute aus dem Manifest mit der höchsten Priorität verwendet.
  • Für das Attribut android:required in den Elementen <uses-feature> und <uses-library> wird eine ODER-Merge verwendet. Bei einem Konflikt wird "true" angewendet und die Funktion oder Bibliothek, die in einem Manifest erforderlich ist, ist immer enthalten.
  • Für Attribute im <uses-sdk>-Element wird immer der Wert aus dem Manifest mit der höheren Priorität verwendet, mit folgenden Ausnahmen:
    • Wenn das Manifest mit der niedrigeren Priorität einen höheren minSdk-Wert hat, tritt ein Fehler auf, es sei denn, Sie wenden die Zusammenführungsregel overrideLibrary an.
    • Wenn das Manifest mit der niedrigeren Priorität einen niedrigeren targetSdkVersion-Wert hat, verwendet das Tool zum Zusammenführen 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 (für Fälle, in denen die höhere Android-Version die Berechtigungseinschränkungen erhöht hat). Weitere Informationen zu diesem Verhalten finden Sie im Abschnitt zu impliziten Systemberechtigungen.
  • Das <intent-filter>-Element wird nie zwischen Manifesten abgeglichen. Jedes wird als eindeutig behandelt und dem gemeinsamen übergeordneten Element im zusammengeführten Manifest hinzugefügt.

Bei allen anderen Attributenkonflikten erhalten Sie eine Fehlermeldung und müssen dem Tool zur Zusammenführung mitteilen, wie der Konflikt gelöst werden soll. Fügen Sie dazu ein spezielles Attribut in die Manifestdatei mit der höheren Priorität ein. Weitere Informationen finden Sie im folgenden Abschnitt Markierungen für Zusammenführungsregeln.

Verlassen Sie sich nicht auf Standardattributwerte. Da alle eindeutigen Attribute in dasselbe Element eingefügt werden, kann dies zu unerwarteten Ergebnissen führen, wenn das Manifest mit der höheren Priorität tatsächlich vom Standardwert eines Attributs abhängt, ohne es zu deklarieren. Wenn das Manifest mit der höheren Priorität beispielsweise das Attribut android:launchMode nicht deklariert, wird der Standardwert "standard" verwendet. Wenn das Manifest mit der niedrigeren Priorität dieses Attribut jedoch mit einem anderen Wert deklariert, wird dieser Wert auf das zusammengeführte Manifest angewendet und überschreibt den Standardwert. Sie sollten jedes Attribut explizit so definieren, wie es sein soll. Die Standardwerte für jedes Attribut sind in der Manifestreferenz dokumentiert.

Regelmarkierungen zusammenführen

Eine Merge-Rule-Markierung ist ein XML-Attribut, mit dem Sie festlegen können, wie Zusammenführungskonflikte gelöst oder unerwünschte Elemente und Attribute entfernt werden sollen. 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 Tool nach diesen Markierungen in der Manifestdatei mit der höheren Priorität.

Alle Markierungen gehören zum Android-Namespace tools. Sie müssen diesen Namespace also zuerst im Element <manifest> deklarieren, wie hier gezeigt:

<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 gesamtes XML-Element anwenden möchten (auf alle Attribute in einem bestimmten Manifest-Element und auf alle untergeordneten Tags), verwenden Sie die folgenden Attribute:

tools:node="merge"
Wenn keine Konflikte auftreten, können Sie alle Attribute in diesem Tag und alle verschachtelten Elemente mithilfe der Heuristiken zum Zusammenführen von Konflikten zusammenführen. 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ügen Sie Attribute nur in diesem Tag zusammen. Verschachtelte Elemente dürfen nicht zusammengeführt werden.

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 Sie nicht benötigen und das von einer Manifestdatei mit niedrigerer Priorität bereitgestellt wurde, die sich nicht in Ihrer Kontrolle befindet (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 aber alle Elemente, die diesem Elementtyp entsprechen (innerhalb desselben übergeordneten Elements).

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 im Manifest mit niedrigerer Priorität ein übereinstimmendes Element vorhanden ist, wird es ignoriert und genau so verwendet, 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"
Jedes Mal, wenn dieses Element im Manifest mit niedrigerer Priorität nicht genau mit dem Element im Manifest mit höherer Priorität übereinstimmt, wird ein Buildfehler generiert (es sei denn, dies wird durch andere Markierungen für Zusammenführungsregeln gelöst). Dadurch werden die Heuristiken für Zusammenführungskonflikte überschrieben. Wenn das Manifest mit der niedrigeren Priorität beispielsweise ein zusätzliches Attribut enthält, schlägt der Build fehl. Beim 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 beim Zusammenführen des Manifests verursacht. Im strengen Modus dürfen sich die beiden Manifestelemente 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 ohne Fehler zusammengeführt werden, wie im Beispiel für tools:node="merge" gezeigt.

Attributmarkierungen

Wenn Sie eine Zusammenführungsregel stattdessen nur auf bestimmte Attribute in einem Manifest-Tag anwenden möchten, verwenden Sie die folgenden Attribute. Für jedes Attribut können ein oder mehrere Attributnamen (einschließlich des Attribut-Namespace) angegeben werden, die durch Kommas getrennt werden.

tools:remove="attr, ..."
Entfernen Sie die angegebenen Attribute aus dem zusammengeführten Manifest. 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 aus diesem Manifest. Mit anderen Worten: Behalten Sie immer die Werte des Manifests mit der höheren 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, ..."
Jedes Mal einen Buildfehler generieren, wenn diese Attribute im Manifest mit niedrigerer Priorität nicht genau mit den Attributen im Manifest mit höherer Priorität übereinstimmen. Das ist das Standardverhalten für alle Attribute, mit Ausnahme derer mit speziellen Verhaltensweisen, wie in den Heuristiken für Zusammenführungskonflikte beschrieben.

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 beim Zusammenführen des Manifests verursacht. Sie müssen andere Markierungen für die Zusammenführungsregel anwenden, um den Konflikt zu beheben. Das ist das Standardverhalten. Das gleiche Ergebnis wird erzielt, wenn Sie tools:strict="screenOrientation" explizit hinzufügen.

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 für die Zusammenführungsregeln nur auf eine bestimmte importierte Bibliothek anwenden möchten, fügen Sie das Attribut tools:selector mit dem Namen des Bibliothekspakets hinzu.

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

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

Wenn das Manifest mit der niedrigeren Priorität aus einer anderen Quelle stammt, wird die remove-Merge-Regel ignoriert.

Hinweis:Wenn Sie diese Option mit einer der Attributmarkierungen verwenden, gilt sie für alle in der Markierung angegebenen Attribute.

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

Wenn Sie eine Bibliothek mit einem minSdk-Wert importieren, der höher als der der Hauptmanifestdatei ist, tritt standardmäßig ein Fehler auf und die Bibliothek kann nicht importiert werden.

Wenn das Zusammenführungstool diesen Konflikt ignorieren und die Bibliothek importieren soll, während der niedrigere minSdk-Wert Ihrer App beibehalten wird, fügen Sie dem <uses-sdk>-Tag das overrideLibrary-Attribut hinzu. Der Attributwert kann einen oder mehrere Bibliothekspaketnamen (durch Kommas getrennt) enthalten, die angeben, welche Bibliotheken minSdk des Hauptmanifests überschreiben können.

Wenn das Hauptmanifest Ihrer App beispielsweise overrideLibrary so anwendet:

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

Dann kann das folgende Manifest ohne Fehler bezüglich des <uses-sdk>-Tags zusammengeführt werden. Im zusammengeführten Manifest bleibt minSdk="2" aus dem App-Manifest erhalten.

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

Implizite Systemberechtigungen

Einige Android APIs, auf die Apps früher frei zugreifen konnten, sind in den neuesten Android-Versionen durch Systemberechtigungen eingeschränkt.

Damit Apps, die Zugriff auf diese APIs erwarten, nicht beschädigt werden, können Apps in den neuesten Android-Versionen weiterhin ohne die Berechtigung auf diese APIs zugreifen, wenn targetSdkVersion auf einen Wert festgelegt ist, der niedriger ist als die Version, in der die Einschränkung hinzugefügt wurde. Dadurch erhält die App eine implizite Berechtigung, den Zugriff auf die APIs zuzulassen. Die zusammengeführten Manifeste mit unterschiedlichen Werten für targetSdkVersion können davon betroffen sein.

Wenn die Manifestdatei mit der niedrigeren Priorität einen niedrigeren Wert für targetSdkVersion hat, der ihr eine implizite Berechtigung verleiht, und das Manifest mit der höheren Priorität nicht dieselbe implizite Berechtigung hat (weil sein targetSdkVersion der Version entspricht oder höher ist, in der die Einschränkung hinzugefügt wurde), fügt das Tool zum Zusammenführen die Systemberechtigung dem zusammengeführten Manifest explizit hinzu.

Wenn Sie in Ihrer App beispielsweise targetSdkVersion auf 4 oder höher festlegen und eine Bibliothek importieren, in der targetSdkVersion auf 3 oder niedriger festgelegt ist, fügt das Tool zum Zusammenführen 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 dem zusammengeführten Manifest möglicherweise vom Tool zum Zusammenführen hinzugefügt werden

Manifest mit niedrigerer Priorität deklariert Dem zusammengeführten Manifest hinzugefügte Berechtigungen
targetSdkVersion ist gleich 3 oder kleiner WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE
targetSdkVersion ist kleiner als 15 und READ_CONTACTS wird verwendet READ_CALL_LOG
targetSdkVersion ist kleiner als 15 und WRITE_CONTACTS wird verwendet WRITE_CALL_LOG

Zusammengeführtes Manifest prüfen und Konflikte finden

Sie können sich schon vor dem Erstellen Ihrer App eine Vorschau des zusammengeführten Manifests ansehen. 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 Merged Manifest (Zusammengeführtes Manifest).

In der Ansicht „Zusammengeführtes Manifest“ werden links die Ergebnisse des zusammengeführten Manifests und rechts Informationen zu den einzelnen zusammengeführten Manifestdateien angezeigt (siehe Abbildung 2).

Die Elemente, die aus Manifestdateien mit niedrigerer Priorität zusammengeführt wurden, sind links in verschiedenen Farben hervorgehoben. Der Schlüssel für jede Farbe wird unter Manifest-Quellen angegeben.

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

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

Wenn Sie Informationen zur Herkunft eines Elements sehen möchten, klicken Sie im linken Bereich darauf. Die Details werden dann unter Merge-Log angezeigt.

Falls Konflikte auftreten, werden sie unter Fehler beim Zusammenführen zusammen mit einer Empfehlung zur Behebung des Konflikts mithilfe von Markierungen für Zusammenführungsregeln angezeigt.

Die Fehler werden auch im Fenster Ereignisprotokoll ausgegeben. Wählen Sie Ansicht > Toolfenster > Ereignisprotokoll aus, um sie aufzurufen.

Ein vollständiges Protokoll des Entscheidungsbaums für die Zusammenführung finden Sie im Verzeichnis build/outputs/logs/ Ihres Moduls unter dem Namen manifest-merger-buildVariant-report.txt.

Richtlinien zusammenführen

Das Tool zum Zusammenführen von Manifesten kann jedes XML-Element aus einer Manifestdatei logisch mit einem entsprechenden Element in einer anderen Datei abgleichen. Bei der Zusammenführung wird jedes Element anhand eines Abgleichsschlüssels abgeglichen. Das kann entweder ein eindeutiger Attributwert (z. B. android:name) oder die natürliche Eindeutigkeit des Tags selbst sein (z. B. kann es nur ein <supports-screen>-Element geben).

Wenn zwei Manifeste dasselbe XML-Element haben, werden die beiden Elemente mit einer der drei Zusammenführungsrichtlinien zusammengeführt:

Zusammenführen
Kombinieren Sie alle Attribute ohne Konflikte in einem Tag und führen Sie die Zusammenführung der untergeordneten Elemente gemäß der jeweiligen Zusammenführungsrichtlinie durch. Wenn Attribute in Konflikt stehen, können Sie sie mithilfe der Markierungen für Zusammenführungsregeln zusammenführen.
Nur untergeordnete Elemente zusammenführen
Kombinieren oder verschmelzen Sie die Attribute nicht. Behalten Sie nur die Attribute bei, die in der Manifestdatei mit der höchsten Priorität angegeben sind. Verschmelzen Sie untergeordnete Elemente gemäß der entsprechenden Richtlinie.
Notizen
Lassen Sie das Element unverändert und fügen Sie es dem gemeinsamen übergeordneten Element in der zusammengeführten Datei hinzu. Dieser Wert wird nur verwendet, wenn mehrere Deklarationen desselben Elements zulässig sind.

In Tabelle 3 sind die einzelnen Elementtypen, die verwendete Zusammenführungsrichtlinie und der Schlüssel aufgeführt, mit dem die Übereinstimmung von Elementen zwischen zwei Manifesten ermittelt wird:

Tabelle 3 Richtlinien für die Zusammenführung von Manifestelementen und Abgleichsschlüssel

Element Richtlinie zusammenführen Abgleichsschlüssel
<action> Zusammenführen android:name-Attribut
<activity> Zusammenführen android:name-Attribut
<application> Zusammenführen Es gibt nur eine pro <manifest>.
<category> Zusammenführen android:name-Attribut
<data> Zusammenführen Es gibt nur eine pro <intent-filter>.
<grant-uri-permission> Zusammenführen Es gibt nur eine pro <provider>.
<instrumentation> Zusammenführen android:name-Attribut
<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 android:name-Attribut
<path-permission> Zusammenführen Es gibt nur eine pro <provider>.
<permission-group> Zusammenführen android:name-Attribut
<permission> Zusammenführen android:name-Attribut
<permission-tree> Zusammenführen android:name-Attribut
<provider> Zusammenführen android:name-Attribut
<receiver> Zusammenführen android:name-Attribut
<screen> Zusammenführen android:screenSize-Attribut
<service> Zusammenführen android:name-Attribut
<supports-gl-texture> Zusammenführen android:name-Attribut
<supports-screen> Zusammenführen Es gibt nur eine pro <manifest>.
<uses-configuration> Zusammenführen Es gibt nur eine pro <manifest>.
<uses-feature> Zusammenführen android:name-Attribut (falls nicht vorhanden, dann das android:glEsVersion-Attribut)
<uses-library> Zusammenführen android:name-Attribut
<uses-permission> Zusammenführen android:name-Attribut
<uses-sdk> Zusammenführen Es gibt nur eine pro <manifest>.
Benutzerdefinierte Elemente Zusammenführen Keine Übereinstimmung; diese Elemente sind dem Tool zum Zusammenführen unbekannt und werden immer in das zusammengeführte Manifest aufgenommen.

Build-Variablen in Manifest einfügen

Wenn Sie Variablen in die AndroidManifest.xml-Datei einfügen möchten, die in der build.gradle-Datei definiert sind, können Sie dies mit dem Attribut manifestPlaceholders tun. Für diese Eigenschaft ist eine Zuordnung von Schlüssel/Wert-Paaren erforderlich, wie hier dargestellt:

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

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

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

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

Angenommen, Ihre build.gradle-Datei sieht so aus:

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

Fügen Sie die Anwendungs-ID dann so in Ihr Manifest ein:

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

Das Manifestergebnis beim Erstellen der „kostenlosen“ Produktvariante sieht so aus:

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

Weitere Informationen finden Sie unter App-ID festlegen.