Strumenti: sostituisci non sostituendo in manifest Android


147

Sto usando un progetto gradle con molte dipendenze di librerie diverse e sto usando la nuova fusione manifest. Nel mio <application />tag l'ho impostato come tale:

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

Eppure sto ricevendo l'errore:

/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

1
Vedi questo post in Meta sull'eliminazione e la re-pubblicazione di domande: meta.stackoverflow.com/questions/265233/… . Farlo una volta non ti farà particolarmente male, ma non sarebbe bene praticarlo regolarmente.
Scott Barta,

1
Immagino che ci sia un <application>tag ripetuto nel progetto. Assicurati che ce ne sia solo uno <application>.
Pantera,

Ci possono essere molti tag <application> in un progetto specialmente se usi un numero qualsiasi di sottomoduli di libreria.
agrosner,

Ho esempi di casi in cui funziona perfettamente. Quale versione degli strumenti di build Android stai usando?
G. Blake Meike,

Risposte:


233

Dichiara l'intestazione manifest in questo modo

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

Quindi è possibile aggiungere al tag dell'applicazione il seguente attributo:

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

Ad esempio, devo sostituire l'icona e l'etichetta. In bocca al lupo!


1
come gestisci android: nome con metadati? android: name = "com.orm.SugarApp"> <meta-data android: name = "DATABASE" android: value = "sv_logs.db" /> <meta-data android: name = "VERSION" android: value = " 3 "/> <meta-dati android: name =" QUERY_LOG "android: value =" true "/> <meta-data android: name =" DOMAIN_PACKAGE_NAME "android: value =" com.example.app "/>
Alan

@Alan Sostituisci semplicemente l'intero tag dei metadati con tools:node="replace": <meta-data tools:node="replace" android:name="QUERY_LOG" android:value="true" />ecc.
Blacklight

25
Non ho capito bene. Non è esattamente quello che sta facendo nella sua domanda?
Jason Robinson,

Ho aggiunto tools:replaceal mio tag applicazione che dovrebbe sostituirlo e non l'origine che dovrebbe essere sostituita. Quindi i manifest della mia app sostituiscono ciò che è definito nella mia libreria. Dici "cosa dovrebbe essere sostituito" invece di "cosa può essere sostituito". Spero che ripulisca le domande.
WarrenFaith,

1
Se l'attributo sostituito è nel tag manifest, tools:replace="android:versionCode, android:versionName"deve essere all'interno del <manifest >tag.
Ivan Chau,

42

Ho risolto lo stesso problema. Soluzione per me:

  1. aggiungi la xmlns:tools="http://schemas.android.com/tools"linea nel tag manifest
  2. aggiungi tools:replace=..il tag manifest
  3. sposta android:label=...nel tag manifest

Esempio:

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

1
Grazie per questo, aggiungerlo <manifest>direttamente al posto di sotto <application>era l'unica cosa che ha risolto il mio problema.
A. Sokol,

1
Non ho funzionato per me, dovrei mettere gli strumenti: sostituisci = "android: allowBackup, android: label" né solo strumenti: sostituisci = "allowBackup, label".
jmarkstar,

1
Sei sicuro che funzioni? Perché per me, sembra che tu stia scrivendo allowBackup nel posto sbagliato, e che dopo l'unione, prevale quello che la Libreria ha specificato sul suo manifest. Non hai un conflitto dopo averlo spostato in alto, perché lo stai facendo semplicemente male ( developer.android.com/guide/topics/manifest/… ) AllowBackup appartiene all'elemento Application.
Reinherd,

2
[... continua dall'alto] NON FUNZIONA. Stai scrivendo allowBackup nel posto sbagliato e che dopo l'unione prevale quello che la Libreria ha specificato sul suo manifest. Non hai un conflitto dopo averlo spostato in alto, perché lo stai facendo semplicemente male ( developer.android.com/guide/topics/manifest/… ) AllowBackup appartiene all'elemento Application. L'ho provato decompilando un APK e il manifest finale aveva il valore VERO invece di FALSO come ho specificato come hai suggerito
Reinherd

38

Prova a riordinare le tue dipendenze nel tuo file gradle. Ho dovuto spostare la libreria offensiva dal fondo dell'elenco verso l'alto, e poi ha funzionato.


per favore dimmi una cosa: sostituire se devo aggiungere questo tag interno dell'applicazione del mio manifest di progetto o all'interno del tag dell'applicazione della mia biblioteca, per favore dimmi che sarà davvero utile per me ??
Sudhanshu Gaur,

@SudhanshuGaur Devi solo aggiungerlo al file AndroidManifest.xml del tuo progetto.
Kyle Liu,

74
Ha funzionato. Ma tali soluzioni possono togliere la fede dall'umanità.
Vinay Patil,

8
#android gotchas come questi rendono lo sviluppo per Android piuttosto fastidioso
Taylor Halliday

1
Nel caso in cui tu abbia più varianti di prodotto come play e non play e la dipendenza sia "playReleaseCompile ______", il semplice spostamento dell'istruzione in alto potrebbe non funzionare, potrebbe essere necessario modificare l'istruzione in "compila ______" e quindi spostarla in superiore. Dovrebbe funzionare allora.
Soham,

33

Ho appena sperimentato lo stesso comportamento tools:replace=...descritto dall'OP.

Si è scoperto che la causa principale per tools:replaceessere ignorata dalla fusione manifest è un bug descritto qui . In pratica significa che se nel tuo progetto è presente una libreria che contiene un manifest con un <application ...>nodo contenente un tools:ignore=...attributo, può succedere che l' tools:replace=...attributo nel manifest del modulo principale venga ignorato.

Il punto difficile qui è che può succedere, ma non è necessario. Nel mio caso avevo due librerie, la libreria A con l' tools:ignore=...attributo, la libreria B con gli attributi da sostituire nei rispettivi manifest e l' tools:replace=...attributo nel manifest del modulo principale. Se il manifest di B è stato unito al manifest principale prima del manifest di A, tutto ha funzionato come previsto. Nell'ordine di unione opposto è apparso l'errore.

L'ordine in cui avvengono queste fusioni sembra essere alquanto casuale. Nel mio caso, cambiare l'ordine nella sezione delle dipendenze build.gradlenon ha avuto alcun effetto, ma ha cambiato il nome del sapore.

Quindi, l'unica soluzione affidabile sembra essere decomprimere il problema che causa la libreria, rimuovere il tools:ignore=...tag (che non dovrebbe essere un problema in quanto è un suggerimento solo per i filacci) e impacchettare nuovamente la libreria.

E vota per il bug da correggere, di causa.


Nel mio caso ho dovuto rimuovere gli strumenti: ignorare dal mio progetto, non da una delle librerie
mohax,

3
Questo è stato anche il mio problema. Spostato gli strumenti: ignora il <manifest>nodo dal <application>nodo e ha funzionato.
Jacob Tabak,

Ho appena riscontrato lo stesso problema con Bazel v2.0.0 ha archiviato un bug qui github.com/bazelbuild/bazel/issues/10543
Nick Korostelev

18

Soluzione di lavoro finale per me (evidenziate le tage nel codice di esempio):

  1. aggiungi la xmlns:toolslinea nel tag manifest
  2. aggiungi tools:replaceil tag dell'applicazione

Esempio:

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

13

Il pezzo mancante per me era questo:

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

per esempio:

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

Puoi condividere il tuo codice esattamente come lo hai nel <manifest ...>?
Partizan,

8

È possibile sostituire quelli nel tag dell'applicazione Manifest:

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

e lavorerà per te.


Non funziona per qualche motivo .... Provo ad aggiungere tools:replace="android:label"all'applicazione ma non funziona
iKK,

4

RISOLTO HA AVUTO L'ERRORE ESATTO, basta aggiungere questi strumenti: sostituisci = "android: icon, android: theme"

nel tag dell'applicazione nel manifest, funziona perfettamente,


è cosa normale. ciò di cui si discute non è il comportamento normale che si verifica in alcuni casi quando anche gli strumenti: sostituisci aggiunto.
David,

4

È possibile sostituire quelli nel applicationtag Manifest :

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

e lavorerà per te.

Spiegazione

L'uso di una tale dipendenza / libreria nel tuo gradlefile che ha quelle etichette nel tag dell'applicazione Manifest può causare questo problema e sostituirli nella tua Manifestè la soluzione.


1

Il seguente hack funziona:

  1. aggiungi la xmlns:tools="http://schemas.android.com/tools"linea nel tag manifest
  2. aggiungi tools:replace="android:icon,android:theme,android:allowBackup,label" il tag dell'applicazione

1

Il mio problema è il progetto multi modulo con modulo base, modulo app e modulo funzionalità. Ogni modulo ha AndroidManifest a sé stante e ho implementato la variante di build per debug e main. Quindi dobbiamo essere sicuri che "android: name" sia appena stato dichiarato in Manifest di debug e main, e non impostarlo in nessuno dei moduli Manifest in child. Es .: Manifest in main:

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

Manifest nel debug:

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

Non impostare "android: name" in altri file manifest come questo:

<application android:name=".App">

Basta definire nel modulo di funzionalità come questo e si fonderà bene

<application> 

0

Stavo ricevendo un errore simile su un progetto che stavo importando:

Più voci con lo stesso tasto: android: icon = REPLACE e strumenti: icon = REPLACE

Risolto dopo aver modificato la riga seguente all'interno del tag dell'applicazione:

tools:replace="icon, label, theme"

per

tools:replace="android:icon, android:label, android:theme"

0

Ho anche riscontrato questo problema e l'ho modificato:

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

per

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.