Tools: Ersetzen, nicht Ersetzen im Android-Manifest

147

Ich verwende ein Gradle-Projekt mit vielen verschiedenen Bibliotheksabhängigkeiten und verwende die neue Manifest-Fusion. In meinem <application />Tag habe ich es als solches eingerichtet:

<application tools:replace="android:icon, android:label, android:theme, android:name"
    android:name="com.example.myapp.MyApplcation"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/application_name"
    android:logo="@drawable/logo_ab"
    android:theme="@style/AppTheme"
    >
....
</application>

Dennoch erhalte ich den Fehler:

/android/MyApp/app/src/main/AndroidManifest.xml:29:9        Error:
Attribute application@icon value=(@drawable/ic_launcher) from AndroidManifest.xml:29:9
is also present at {Library Name} value=(@drawable/app_icon)
Suggestion: add 'tools:replace="android:icon"' to <application> element at AndroidManifest.xml:26:5 to override

/android/MyApp/app/src/main/AndroidManifest.xml:30:9 Error:
Attribute application@label value=(@string/application_name) from AndroidManifest.xml:30:9
is also present at {Library Name} value=(@string/app_name)
Suggestion: add 'tools:replace="android:label"' to <application> element at AndroidManifest.xml:26:5 to override

/android/MyApp/app/src/main/AndroidManifest.xml:27:9 Error:
Attribute application@name value=(com.example.myapp.MyApplication) from AndroidManifest.xml:27:9
is also present at {Another Library}

Suggestion: add 'tools:replace="android:name"' to <application> element at AndroidManifest.xml:26:5 to override

/android/MyApp/app/src/main/AndroidManifest.xml:32:9 Error:
Attribute application@theme value=(@style/AppTheme) from AndroidManifest.xml:32:9
is also present at {Library Name} value=(@style/AppTheme)
Suggestion: add 'tools:replace="android:theme"' to <application> element at AndroidManifest.xml:26:5 to override
Agrosner
quelle
1
Lesen Sie diesen Beitrag in Meta zum Löschen und erneuten Posten von Fragen: meta.stackoverflow.com/questions/265233/… . Dies einmal zu tun schadet Ihnen nicht besonders, aber es wäre nicht gut, es regelmäßig zu üben.
Scott Barta
1
Ich denke, es wird ein <application>Tag im Projekt wiederholt. Bitte stellen Sie sicher, dass es nur einen gibt <application>.
Panther
In einem Projekt können viele <application> -Tags vorhanden sein, insbesondere wenn Sie eine beliebige Anzahl von Bibliotheks-Submodulen verwenden.
Agrosner
Ich habe Beispiele für Fälle, in denen dies gut funktioniert. Welche Version der Android-Build-Tools verwenden Sie?
G. Blake Meike

Antworten:

233

Deklarieren Sie Ihren Manifest-Header wie folgt

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

Anschließend können Sie Ihrem Anwendungstag das folgende Attribut hinzufügen:

<application
    tools:replace="icon, label" ../>

Zum Beispiel muss ich Symbol und Beschriftung ersetzen. Viel Glück!

Andrus
quelle
1
Wie gehst du mit Android: Name mit Metadaten um? android: name = "com.orm.SugarApp"> <Metadaten android: name = "DATABASE" android: value = "sv_logs.db" /> <metadaten android: name = "VERSION" android: value = " 3 "/> <Metadaten android: name =" QUERY_LOG "android: value =" true "/> <Metadaten android: name =" DOMAIN_PACKAGE_NAME "android: value =" com.example.app "/>
Alan
@ Alan Ersetzen Sie einfach das gesamte Metadaten-Tag durch tools:node="replace": <meta-data tools:node="replace" android:name="QUERY_LOG" android:value="true" />usw.
Blacklight
25
Ich bin verwirrt. Ist es nicht genau das, was er in seiner Frage tut?
Jason Robinson
Ich tools:replacehabe meinem Anwendungs-Tag hinzugefügt , das es ersetzen soll, und nicht die Quelle, die ersetzt werden soll. Meine App-Manifeste ersetzen also das, was in meiner Bibliothek definiert ist. Sie sagen "was ersetzt werden soll" anstelle von "was ersetzt werden kann". Ich hoffe das räumt die Fragen auf.
WarrenFaith
1
Wenn sich das ersetzte Attribut im Manifest-Tag befindet, tools:replace="android:versionCode, android:versionName"muss sich das Attribut im <manifest >Tag befinden.
Ivan Chau
42

Ich habe das gleiche Problem behoben. Lösung für mich:

  1. Ergänzen Sie die xmlns:tools="http://schemas.android.com/tools" Zeile in das Manifest-Tag ein
  2. Fügen Sie tools:replace=..das Manifest-Tag hinzu
  3. Verschieben Sie android:label=...das Manifest-Tag

Beispiel:

 <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
              tools:replace="allowBackup, label"
              android:allowBackup="false"
              android:label="@string/all_app_name"/>
stefan K.
quelle
1
Vielen Dank dafür, dass das Hinzufügen von <manifest>direkt anstelle von unter <application>das einzige war, was mein Problem behoben hat.
A. Sokol
1
Ich habe nicht für mich gearbeitet, ich sollte tools setzen: replace = "android: allowBackup, android: label" noch nur tools: replace = "allowBackup, label".
Jmarkstar
1
Bist du sicher, dass das funktioniert? Für mich sieht es so aus, als würden Sie das allowBackup an der falschen Stelle schreiben, und nach dem Zusammenführen hat das Vorrang, was die Bibliothek in seinem Manifest angegeben hat. Sie haben keinen Konflikt, nachdem Sie ihn nach oben verschoben haben , weil Sie ihn nur falsch machen ( developer.android.com/guide/topics/manifest/… ). AllowBackup gehört zum Anwendungselement.
Reinherd
2
[... fährt von oben fort] DAS FUNKTIONIERT NICHT. Sie schreiben das allowBackup an der falschen Stelle, und nach dem Zusammenführen hat das Vorrang, was die Bibliothek in seinem Manifest angegeben hat. Sie haben keinen Konflikt, nachdem Sie ihn nach oben verschoben haben , weil Sie ihn nur falsch machen ( developer.android.com/guide/topics/manifest/… ). AllowBackup gehört zum Anwendungselement. Ich habe es getestet, indem ich eine APK dekompiliert habe, und das endgültige Manifest hatte den Wert TRUE anstelle von FALSE, wie ich angegeben habe, wie Sie vorgeschlagen haben
Reinherd
38

Versuchen Sie, Ihre Abhängigkeiten in Ihrer Gradle-Datei neu zu ordnen. Ich musste die fehlerhafte Bibliothek vom Ende der Liste nach oben verschieben, und dann funktionierte es.

Freude
quelle
Bitte sagen Sie mir eines: Wenn ich dieses Tag innerhalb des Anwendungs-Tags meines Projektmanifests oder innerhalb des Anwendungs-Tags meiner Bibliothek hinzufügen soll, sagen Sie mir bitte, dass es für mich wirklich hilfreich sein wird.
Sudhanshu Gaur
@SudhanshuGaur Sie müssen es nur zur Datei AndroidManifest.xml Ihres Projekts hinzufügen.
Kyle Liu
74
Es funktionierte. Aber solche Lösungen können der Menschheit den Glauben nehmen.
Vinay Patil
8
#android Fallstricke wie diese machen die Entwicklung für Android ziemlich nervig
Taylor Halliday
1
Wenn Sie mehrere Produktvarianten wie "Play" und "Non Play" haben und die Abhängigkeit "playReleaseCompile ______" lautet, funktioniert es möglicherweise nicht, die Anweisung nach oben zu verschieben. Möglicherweise müssen Sie die Anweisung in "compile ______" ändern und dann in die oben. Es sollte dann funktionieren.
Soham
33

Ich habe gerade das gleiche Verhalten von erlebt tools:replace=... wie vom OP beschrieben .

Es stellte sich heraus, dass die Hauptursache für tools:replacedas Ignorieren bei der Manifest-Fusion ein hier beschriebener Fehler ist . Grundsätzlich bedeutet dies, dass wenn Sie in Ihrem Projekt eine Bibliothek haben, die ein Manifest mit einem <application ...>Knoten enthält, der ein tools:ignore=...Attribut enthält , das tools:replace=...Attribut im Manifest Ihres Hauptmoduls ignoriert wird.

Der schwierige Punkt hier ist, dass es passieren kann , aber nicht muss. In meinem Fall hatte ich zwei Bibliotheken, Bibliothek A mit dem tools:ignore=...Attribut, Bibliothek B mit den Attributen, die in den jeweiligen Manifesten ersetzt werden sollen, und das tools:replace=...Attribut im Manifest des Hauptmoduls. Wenn das Manifest von B vor dem Manifest von A mit dem Hauptmanifest zusammengeführt wurde, funktionierte alles wie erwartet. In umgekehrter Reihenfolge trat der Fehler auf.

Die Reihenfolge, in der diese Zusammenführungen stattfinden, scheint etwas zufällig zu sein. In meinem Fall hatte das Ändern der Reihenfolge im Abhängigkeitsabschnitt von build.gradlekeine Auswirkung, aber das Ändern des Namens des Geschmacks hat es getan.

Die einzige zuverlässige Problemumgehung scheint darin zu bestehen, das Problem, das die Bibliothek verursacht, zu entpacken, das tools:ignore=...Tag zu entfernen (was kein Problem sein sollte, da es nur ein Hinweis für Flusen ist) und die Bibliothek erneut zu packen.

Und stimmen Sie dafür, dass der Fehler behoben wird.

Nantoka
quelle
In meinem Fall musste ich Tools entfernen: Ignorieren Sie aus meinem Projekt, nicht aus einer der Bibliotheken
Mohax
3
Dies war auch mein Problem. Die Tools wurden verschoben: <manifest>Vom <application>Knoten auf den Knoten ignorieren und es hat funktioniert.
Jacob Tabak
Nur begegnet das gleiche Problem mit Bazel v2.0.0 einen Fehler hier eingereicht github.com/bazelbuild/bazel/issues/10543
Nick Korostelev
18

Endgültige Arbeitslösung für mich (Hervorgehoben die Stufen im Beispielcode):

  1. Fügen Sie diexmlns:tools Zeile in das Manifest-Tag ein
  2. Fügen Sie tools:replacedas Anwendungs-Tag hinzu

Beispiel:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="pagination.yoga.com.tamiltv"
    **xmlns:tools="http://schemas.android.com/tools"**
    >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        **tools:replace="android:icon,android:theme"**
        >
Yogamurthy
quelle
13

Das fehlende Stück für mich war das:

xmlns:tools="http://schemas.android.com/tools"

beispielsweise:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
    package="com.your.appid">
Partizan
quelle
Können Sie Ihren Code genau so teilen, wie Sie ihn im <Manifest ...> haben?
Partizan
8

Sie können diese in Ihrem Manifest-Anwendungs-Tag ersetzen:

<application
    tools:replace="android:icon, android:label, android:theme, android:name,android:allowBackup"
android:allowBackup="false"...>

und wird für Sie arbeiten.

Saurabh Gaddelpalliwar
quelle
Es funktioniert aus irgendeinem Grund nicht .... Ich versuche, tools:replace="android:label"zur Anwendung hinzuzufügen , aber es funktioniert nicht
iKK
4

BEHOBEN DEN einfach diese Tools hinzu: replace = "android: icon, android: theme"

in Ihrem Anwendungs- Tag in Ihrem Manifest funktioniert es einwandfrei,

Ismael Ozil
quelle
Es ist normal. Worum es geht, ist, dass in einigen Fällen kein normales Verhalten auftritt, wenn sogar Tools: Ersetzen hinzugefügt werden.
David
4

Sie können diese in Ihrem Manifest- applicationTag ersetzen :

<application
    ...
    tools:replace="android:label, android:icon, android:theme"/>

und wird für Sie arbeiten.

Erläuterung

Die Verwendung einer solchen Abhängigkeit / Bibliothek in Ihrer gradleDatei, die diese Beschriftungen im Anwendungstag des Manifests enthält, kann dieses Problem verursachen, und das Ersetzen dieser Beschriftungen in Ihrer Manifestist die Lösung.

Blueware
quelle
1

Der folgende Hack funktioniert:

  1. Fügen Sie die xmlns:tools="http://schemas.android.com/tools"Zeile in das Manifest-Tag ein
  2. Fügen Sie tools:replace="android:icon,android:theme,android:allowBackup,label" das Anwendungs-Tag hinzu
Shoaib Ahmed
quelle
1

Mein Problem ist ein Multi-Modul-Projekt mit Basismodul, App-Modul und Feature-Modul. Jedes Modul hat ein eigenes AndroidManifest, und ich habe eine Build-Variante für Debug und Main implementiert. Wir müssen also sicherstellen, dass "android: name" gerade in Manifest of Debug und Main deklariert wurde, und es in keinem der Manifest in Child-Module festlegen. Bsp.: Manifest in main:

 <application
        android:name=".App"/>

Manifest im Debug:

<application
        tools:replace="android:name"
        android:name=".DebugApp"
        />

Setzen Sie "android: name" nicht in anderen Manifest-Dateien wie folgt:

<application android:name=".App">

Definieren Sie einfach im Feature-Modul wie folgt und es wird gut zusammengeführt

<application> 
Hoang Minh
quelle
0

Ich habe einen ähnlichen Fehler bei einem Projekt erhalten, das ich importiert habe:

Mehrere Einträge mit demselben Schlüssel: android: icon = REPLACE und tools: icon = REPLACE

Behoben nach dem Ändern der folgenden Zeile innerhalb des Anwendungs-Tags:

tools:replace="icon, label, theme"

zu

tools:replace="android:icon, android:label, android:theme"
Brybry
quelle
0

Ich habe auch dieses Problem durchgearbeitet und Folgendes geändert:

<application  android:debuggable="true" android:icon="@drawable/app_icon" android:label="@string/app_name" android:supportsRtl="true" android:allowBackup="false" android:fullBackupOnly="false" android:theme="@style/UnityThemeSelector">

zu

 <application tools:replace="android:allowBackup" android:debuggable="true" android:icon="@drawable/app_icon" android:label="@string/app_name" android:supportsRtl="true" android:allowBackup="false" android:fullBackupOnly="false" android:theme="@style/UnityThemeSelector">
Saeed Aliakbari
quelle
0
 tools:replace="android:supportsRtl,android:allowBackup,icon,label">
Android Studio
quelle