Ferramentas: substituir não substituindo no manifesto do Android


147

Estou usando um projeto gradle com muitas dependências de bibliotecas diferentes e usando a nova fusão de manifestos. Na minha <application />tag, eu o configurei assim:

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

No entanto, estou recebendo o erro:

/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
Veja esta postagem no Meta sobre como excluir e republicar perguntas: meta.stackoverflow.com/questions/265233/… . Fazer isso uma vez não irá prejudicá-lo particularmente, mas não seria bom praticar regularmente.
Scott Barta 22/09

1
Eu acho que há uma <application>tag repetida no projeto. Pls garantir que há apenas um <application>.
Panther

Pode haver muitas tags <application> em um projeto, especialmente se você usar qualquer número de submódulos de biblioteca.
agrosner 22/09

Eu tenho exemplos de casos em que isso funciona muito bem. Qual versão das ferramentas de compilação do Android você está usando?
G. Blake Meike 10/10

Respostas:


233

Declare o cabeçalho do manifesto assim

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

Em seguida, você pode adicionar à sua tag de aplicativo o seguinte atributo:

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

Por exemplo, preciso substituir o ícone e o rótulo. Boa sorte!


1
como você lida com android: name com metadados? android: name = "com.orm.SugarApp"> <meta-data android: name = "DATABASE" android: value = "sv_logs.db" /> <meta-data android: name = "VERSÃO" android: value = " 3 "/> <meta-data android: name =" QUERY_LOG "android: value =" true "/> <meta-data android: name =" DOMAIN_PACKAGE_NAME "android: value =" com.example.app "/>
Alan

@ Alan Simplesmente substitua a tag de metadados inteira por tools:node="replace": <meta-data tools:node="replace" android:name="QUERY_LOG" android:value="true" />etc.
Blacklight

25
Estou confuso. Não é exatamente isso que ele está fazendo em sua pergunta?
21415 Jason Robinson

Eu adicionei tools:replaceà minha tag de aplicativo que deve substituí-lo e não a fonte que deve ser substituída. Portanto, meus manifestos de aplicativos substituem o que está definido na minha biblioteca. Você diz "o que deve ser substituído" em vez de "o que pode ser substituído". Espero que isso limpe as perguntas.
WarrenFaith

1
Se o atributo substituído estiver na marca de manifesto, a marca tools:replace="android:versionCode, android:versionName"deve estar dentro <manifest >.
Ivan Chau

42

Corrigi o mesmo problema. Solução para mim:

  1. adicione a xmlns:tools="http://schemas.android.com/tools"linha na tag manifest
  2. adicionar tools:replace=..na tag manifest
  3. mover android:label=...na tag manifest

Exemplo:

 <?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
Obrigado por isso, adicioná-lo <manifest>diretamente ao invés de abaixo <application>foi a única coisa que corrigiu meu problema.
A. Sokol 30/01

1
Eu não trabalhei para mim, devo colocar as ferramentas: replace = "android: allowBackup, android: label" nem apenas ferramentas: replace = "allowBackup, label".
jmarkstar

1
Tem certeza de que isso está funcionando? Porque para mim, parece que você está escrevendo o allowBackup no lugar errado e que, após a mesclagem, prevalece o que a Biblioteca especificou em seu manifesto. Você não tem um conflito depois de movê-lo para cima, porque está fazendo errado ( developer.android.com/guide/topics/manifest/… ) AllowBackup pertence ao elemento Application.
Reinherd

2
[... continua de cima] ISSO NÃO FUNCIONA. Você está escrevendo o allowBackup no lugar errado e, após a mesclagem, o que a Biblioteca especificou em seu manifesto prevalece. Você não tem um conflito depois de movê-lo para cima, porque está fazendo errado ( developer.android.com/guide/topics/manifest/… ) AllowBackup pertence ao elemento Application. Eu testei-o por Decompiling um APK, eo manifesto final apresentou o valor como VERDADEIRO em vez de FALSE como eu especificado como você sugeriu
Reinherd

38

Tente reordenar suas dependências no arquivo gradle. Eu tive que mover a biblioteca ofensiva da parte inferior da lista para o topo, e então funcionou.


por favor me diga uma coisa: substituir devo adicionar essa tag de aplicativo interno do manifesto do projeto ou a tag de aplicativo interno da minha biblioteca, por favor me diga que será realmente útil para mim ??
Sudhanshu Gaur

@SudhanshuGaur Você só precisa adicioná-lo ao arquivo AndroidManifest.xml do seu projeto.
Kyle Liu

74
Funcionou. Mas essas soluções podem tirar a fé da humanidade.
Vinay Patil

8
gotchas #android como estes fazem desenvolver para o Android muito chato
Taylor Halliday

1
Caso você tenha vários tipos de produtos, como play e non play, e a dependência seja "playReleaseCompile ______", apenas mover a instrução para o topo pode não funcionar, talvez seja necessário alterar a instrução para "compilar ______" e movê-la para o topo. Deve funcionar então.
Soham

33

Acabei de experimentar o mesmo comportamento tools:replace=...descrito pelo OP.

Descobriu-se que a causa principal por tools:replaceser ignorada pela fusão do manifesto é um bug descrito aqui . Basicamente, significa que, se você possui uma biblioteca em seu projeto que contém um manifesto com um <application ...>nó que contém um tools:ignore=...atributo, pode acontecer que o tools:replace=...atributo no manifesto do seu módulo principal seja ignorado.

O ponto complicado aqui é que isso pode acontecer, mas não precisa. No meu caso, eu tinha duas bibliotecas, a biblioteca A com o tools:ignore=...atributo, a biblioteca B com os atributos a serem substituídos nos respectivos manifestos e o tools:replace=...atributo no manifesto do módulo principal. Se o manifesto de B foi mesclado no manifesto principal antes do manifesto de A, tudo funcionou conforme o esperado. Na ordem de mesclagem oposta, o erro apareceu.

A ordem em que essas fusões acontecem parece ser um pouco aleatória. No meu caso, alterar a ordem na seção de dependências build.gradlenão teve efeito, mas alterar o nome do sabor fez isso.

Portanto, a única solução confiável parece ser descompactar o problema que está causando a biblioteca, remover a tools:ignore=...tag (o que não deve ser problema, pois é apenas uma dica para o fiapo) e empacotar a biblioteca novamente.

E vote na correção do bug, da causa.


No meu caso eu tive que remover ferramentas: ignore do meu projeto, não a partir de uma das bibliotecas
mohax

3
Este também foi o meu problema. Movidas as ferramentas: ignore para o <manifest>nó a partir do <application>nó e funcionou.
Jacob Tabak

Acabei de encontrar o mesmo problema com o Bazel v2.0.0 registrou um erro aqui github.com/bazelbuild/bazel/issues/10543
Nick Korostelev

18

Solução de trabalho final para mim (destacadas as vantagens no código de exemplo):

  1. adicione a xmlns:toolslinha na tag manifest
  2. adicione tools:replacea tag do aplicativo

Exemplo:

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

A peça que faltava para mim era esta:

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

por exemplo:

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

Você pode compartilhar seu código exatamente como o possui no <manifesto ...>?
Partizan

8

Você pode substituir os da tag do aplicativo Manifest:

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

e funcionará para você.


Ele não funciona por algum motivo .... eu tento adicionar tools:replace="android:label"a aplicação, mas ele não funciona
IKK

4

CORRIGIDO COM ERRO EXATO, basta adicionar estas ferramentas: replace = "android: icon, android: theme"

na tag do aplicativo no manifesto, funciona muito bem,


é coisa normal. o que é tópico não é o comportamento normal acontece em alguns casos, mesmo quando as ferramentas: substituem adicionadas.
David

4

Você pode substituir aqueles em sua applicationtag de manifesto :

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

e funcionará para você.

Explicação

O uso de uma dependência / biblioteca em seu gradlearquivo com esses rótulos na tag de aplicativo do manifesto pode produzir esse problema e substituí-los na sua Manifesté a solução.


1

O seguinte hack funciona:

  1. adicione a xmlns:tools="http://schemas.android.com/tools"linha na tag manifest
  2. adicione tools:replace="android:icon,android:theme,android:allowBackup,label" a tag do aplicativo

1

Meu problema é projeto de múltiplos módulos com módulo base, módulo de aplicativo e módulo de recurso. Cada módulo possui o AndroidManifest próprio e eu implementei a variante de compilação para depuração e principal. Portanto, devemos garantir que "android: name" seja declarado apenas no Manifest de depuração e apenas no main, e não o configure em nenhum dos módulos Manifest no filho. Ex: Manifesto principal:

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

Manifesto na depuração:

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

Não defina "android: name" em outros arquivos de manifesto como este:

<application android:name=".App">

Basta definir no módulo de recursos como este e ele será mesclado

<application> 

0

Eu estava recebendo um erro semelhante em um projeto que estava importando:

Várias entradas com a mesma chave: android: icon = REPLACE e ferramentas: icon = REPLACE

Corrigido após alterar a linha abaixo na tag do aplicativo:

tools:replace="icon, label, theme"

para

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

0

Eu também passei por esse problema e mudei isso:

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

para

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.