Herramientas: reemplazar no reemplazar en manifiesto de Android


147

Estoy usando un proyecto gradle con muchas dependencias de biblioteca diferentes y estoy usando la nueva fusión de manifiesto. En mi <application />etiqueta lo tengo configurado como tal:

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

Sin embargo, estoy recibiendo el error:

/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
Vea esta publicación en Meta sobre cómo eliminar y volver a publicar preguntas: meta.stackoverflow.com/questions/265233/… . Hacer esto una vez no te dañará particularmente, pero no sería bueno practicarlo regularmente.
Scott Barta

1
Supongo que hay una <application>etiqueta repetida en el proyecto. Por favor asegúrese de que solo haya uno <application>.
Panther

Puede haber muchas etiquetas <application> en un proyecto, especialmente si usa cualquier número de submódulos de biblioteca.
agrosner

Tengo ejemplos de casos en los que esto funciona bien. ¿Qué versión de las herramientas de compilación de Android estás usando?
G. Blake Meike

Respuestas:


233

Declara tu encabezado manifiesto de esta manera

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

Luego puede agregar a su etiqueta de aplicación el siguiente atributo:

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

Por ejemplo, necesito reemplazar el ícono y la etiqueta. ¡Buena suerte!


1
¿Cómo manejas Android: nombre con metadatos? android: name = "com.orm.SugarApp"> <metadatos android: name = "DATABASE" android: value = "sv_logs.db" /> <metadatos android: name = "VERSION" android: value = " 3 "/> <metadatos android: name =" QUERY_LOG "android: value =" true "/> <metadatos android: name =" DOMAIN_PACKAGE_NAME "android: value =" com.example.app "/>
Alan

@ Alan Simplemente reemplace toda la etiqueta de metadatos con tools:node="replace": <meta-data tools:node="replace" android:name="QUERY_LOG" android:value="true" />etc.
Blacklight

25
Estoy confundido. ¿No es eso exactamente lo que está haciendo en su pregunta?
Jason Robinson

Agregué tools:replacea mi etiqueta de aplicación que debería reemplazarla y no la fuente que debería reemplazarse. Entonces, los manifiestos de mi aplicación reemplazan lo definido en mi biblioteca. Usted dice "qué se debe reemplazar" en lugar de "qué se puede reemplazar". Espero que eso aclare las preguntas.
WarrenFaith

1
Si el atributo reemplazado está en la etiqueta de manifiesto, tools:replace="android:versionCode, android:versionName"debe estar dentro de la <manifest >etiqueta.
Ivan Chau

42

Solucioné el mismo problema. Solución para mi:

  1. agregue la xmlns:tools="http://schemas.android.com/tools"línea en la etiqueta de manifiesto
  2. agregar tools:replace=..en la etiqueta de manifiesto
  3. moverse android:label=...en la etiqueta de manifiesto

Ejemplo:

 <?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
Gracias por esto, agregarlo <manifest>directamente en lugar de debajo <application>fue lo único que solucionó mi problema.
A. Sokol

1
No funcionó para mí, debería poner herramientas: replace = "android: allowBackup, android: label" ni solo herramientas: replace = "allowBackup, label".
jmarkstar

1
¿Estás seguro de que esto está funcionando? Porque para mí, parece que estás escribiendo allowBackup en el lugar equivocado, y que después de la fusión, prevalece lo que la Biblioteca especificó en su manifiesto. No tiene un conflicto después de moverlo hacia arriba, porque lo está haciendo mal ( developer.android.com/guide/topics/manifest/… ) AllowBackup pertenece al elemento Aplicación.
Reinherd

2
[... continúa desde arriba] ESTO NO FUNCIONA. Estás escribiendo el allowBackup en el lugar equivocado, y después de la fusión, prevalece lo que la Biblioteca especificó en su manifiesto. No tiene un conflicto después de moverlo hacia arriba, porque lo está haciendo mal ( developer.android.com/guide/topics/manifest/… ) AllowBackup pertenece al elemento Aplicación. Lo probé descompilando un APK, y el manifiesto final tenía el valor VERDADERO en lugar de FALSO como especifiqué como sugirió
Reinherd

38

Intente reordenar sus dependencias en su archivo gradle. Tuve que mover la biblioteca ofensiva de la parte inferior de la lista a la parte superior, y luego funcionó.


dígame una cosa: reemplazar. ¿Debería agregar esta etiqueta de aplicación interna de mi manifiesto de proyecto o la etiqueta de aplicación interna de mi biblioteca, por favor dígame que será realmente útil para mí?
Sudhanshu Gaur

@SudhanshuGaur Solo necesita agregarlo al archivo AndroidManifest.xml de su proyecto.
Kyle Liu

74
Funcionó. Pero tales soluciones pueden sacar la fe de la humanidad.
Vinay Patil

8
#compras de Android como estas hacen que el desarrollo para Android sea bastante molesto
Taylor Halliday

1
En caso de que tenga varios sabores de productos como jugar y no jugar y la dependencia es "playReleaseCompile ______", simplemente mover la declaración al principio podría no funcionar, es posible que tenga que cambiar la declaración a "compilar ______" y luego moverla a parte superior. Debería funcionar entonces.
Soham

33

Acabo de experimentar el mismo comportamiento tools:replace=...descrito por el OP.

Resultó que la causa raíz de tools:replaceser ignorado por la fusión de manifiesto es un error descrito aquí . Básicamente significa que si tiene una biblioteca en su proyecto que contiene un manifiesto con un <application ...>nodo que contiene un tools:ignore=...atributo, puede suceder que tools:replace=...se ignore el atributo en el manifiesto de su módulo principal.

El punto difícil aquí es que puede suceder, pero no es necesario. En mi caso, tenía dos bibliotecas, la biblioteca A con el tools:ignore=...atributo, la biblioteca B con los atributos que se reemplazarían en los manifiestos respectivos y el tools:replace=...atributo en el manifiesto del módulo principal. Si el manifiesto de B se fusionó con el manifiesto principal antes del manifiesto de A, todo funcionó como se esperaba. En orden de fusión opuesto, apareció el error.

El orden en que ocurren estas fusiones parece ser algo aleatorio. En mi caso, cambiar el orden en la sección de dependencias build.gradleno tuvo ningún efecto, pero cambiar el nombre del sabor lo hizo.

Por lo tanto, la única solución confiable parece ser desempaquetar el problema que causa la biblioteca, eliminar la tools:ignore=...etiqueta (que no debería ser un problema, ya que es solo una pista para la pelusa) y empacar la biblioteca nuevamente.

Y vote para que se solucione el error, por causa.


En mi caso, tuve que eliminar herramientas: ignorar de mi proyecto, no de una de las bibliotecas
mohax

3
Este también fue mi problema. Se movieron las herramientas: ignorar al <manifest>nodo desde el <application>nodo y funcionó.
Jacob Tabak

Acabo de encontrar el mismo problema con Bazel v2.0.0 presentó un error aquí github.com/bazelbuild/bazel/issues/10543
Nick Korostelev

18

Solución de trabajo final para mí (destacó los valores en el código de muestra):

  1. agregue la xmlns:toolslínea en la etiqueta de manifiesto
  2. agregar tools:replaceen la etiqueta de la aplicación

Ejemplo:

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

La pieza que faltaba para mí era esta:

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

por ejemplo:

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

¿Puedes compartir tu código exactamente como lo tienes en el <manifiesto ...>?
partizan

8

Puede reemplazarlos en su etiqueta de aplicación Manifiesto:

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

y trabajará para ti


No funciona por alguna razón ... Intento agregar tools:replace="android:label"a la aplicación pero no funciona
iKK

4

CORREGIDO TENÍA EL ERROR EXACTO, solo agregue estas herramientas: replace = "android: icon, android: theme"

en su etiqueta de aplicación en su manifiesto, funciona bien,


Es lo normal. de lo que se trata el tema no es que el comportamiento normal ocurre en algunos casos cuando incluso las herramientas: reemplazar agregan.
David

4

Puede reemplazar aquellos en su applicationetiqueta Manifiesto :

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

y trabajará para ti

Explicación

El uso de dicha dependencia / biblioteca en su gradlearchivo que tenga esas etiquetas en la etiqueta de aplicación de su Manifiesto puede producir este problema y reemplazarlas en su Manifestes la solución.


1

El siguiente truco funciona:

  1. agregue la xmlns:tools="http://schemas.android.com/tools"línea en la etiqueta de manifiesto
  2. agregar tools:replace="android:icon,android:theme,android:allowBackup,label" en la etiqueta de la aplicación

1

Mi problema es el proyecto de módulos múltiples con módulo base, módulo de aplicación y módulo de funciones. Cada módulo tiene AndroidManifest propio, e implementé una variante de compilación para depuración y main. Por lo tanto, debemos asegurarnos de que "android: name" acaba de declararse en Manifiesto de depuración y principal únicamente, y no lo establezca en ninguno de Manifiesto en el módulo secundario. Ej: Manifiesto en principal:

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

Manifiesto en depuración:

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

No establezca "android: name" en otros archivos de manifiesto como este:

<application android:name=".App">

Simplemente defina en un módulo de características como este y se fusionará bien

<application> 

0

Estaba recibiendo un error similar en un proyecto que estaba importando:

Múltiples entradas con la misma clave: android: icon = REPLACE y herramientas: icon = REPLACE

Se corrigió después de cambiar la siguiente línea dentro de la etiqueta de la aplicación:

tools:replace="icon, label, theme"

a

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

0

También pasé por este problema y cambié eso:

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

a

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.