React-native: [Android] Erro: recursos duplicados

Criado em 10 nov. 2018  ·  103Comentários  ·  Fonte: facebook/react-native

Meio Ambiente

React Native Environment Info:

System:
  OS: macOS 10.14
  CPU: (4) x64 Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
  Memory: 103.10 MB / 8.00 GB
  Shell: 3.2.57 - /bin/bash
Binaries:
  Node: 8.12.0 - /usr/local/bin/node
  Yarn: 1.0.1 - /usr/local/bin/yarn
  npm: 6.4.1 - /usr/local/bin/npm
  Watchman: 4.7.0 - /usr/local/bin/watchman
SDKs:
  iOS SDK:
    Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
  Android SDK:
    API Levels: 16, 17, 19, 21, 23, 24, 25, 26, 27, 28
    Build Tools: 19.1.0, 20.0.0, 23.0.1, 23.0.2, 23.0.3, 25.0.0, 25.0.1, 25.0.2, 25.0.3, 26.0.0, 26.0.1, 26.0.2, 26.0.3, 27.0.0, 27.0.1, 27.0.3, 28.0.0, 28.0.0, 28.0.2, 28.0.3
    System Images: android-16 | ARM EABI v7a, android-16 | MIPS, android-16 | Intel x86 Atom, android-16 | Google APIs Intel x86 Atom, android-19 | Google APIs Intel x86 Atom, android-24 | Google Play Intel x86 Atom, android-26 | Google APIs Intel x86 Atom, android-26 | Google APIs Intel x86 Atom_64, android-26 | Google Play Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-P | Google APIs Intel x86 Atom, android-P | Google Play Intel x86 Atom
IDEs:
  Android Studio: 3.2 AI-181.5540.7.32.5056338
  Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
  react: 16.6.0-alpha.8af6728 => 16.6.0-alpha.8af6728 
  react-native: 0.57.4 => 0.57.4 
npmGlobalPackages:
  babel-preset-react-native: 4.0.0
  react-native-cli: 2.0.1
  react-native-create-library: 3.1.2
  react-native-git-upgrade: 0.2.7

Descrição

Não consigo criar um apk de lançamento com a imagem PNG no Android. Mas pode criar um apk de lançamento quando não há imagem PNG nele. Aqui está o erro que estou obtendo ao gerar a versão de lançamento

[drawable-mdpi-v4/assets_mario] /Users/jeffreyrajan/Tutorials/RN/errorCheck/android/app/src/main/res/drawable-mdpi/assets_mario.png [drawable-mdpi-v4/assets_mario] /Users/jeffreyrajan/Tutorials/RN/errorCheck/android/app/build/generated/res/react/release/drawable-mdpi-v4/assets_mario.png: Error: Duplicate resources
:app:mergeReleaseResources FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeReleaseResources'.
> [drawable-mdpi-v4/assets_mario] /Users/jeffreyrajan/Tutorials/RN/errorCheck/android/app/src/main/res/drawable-mdpi/assets_mario.png   [drawable-mdpi-v4/assets_mario] /Users/jeffreyrajan/Tutorials/RN/errorCheck/android/app/build/generated/res/react/release/drawable-mdpi-v4/assets_mario.png: Error: Duplicate resources

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Demonstração reproduzível

  1. Crie um aplicativo - react-native init demo
  2. Crie uma pasta assets na pasta raiz do projeto.
  3. Adicione uma imagem PNG dentro da pasta de ativos.
  4. Agora implemente um componente image com a imagem PNG acima.
  5. Agora empacote-o usando o cmd
    react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
  6. Em seguida, gere o apk de liberação usando Generate Signed APK
Bug Android

Comentários muito úteis

A resposta do Mapsy deve ajudar https://stackoverflow.com/a/52750886
Basicamente, você edita o arquivo /node_modules/react-native/react.gradle
e adicione o doLast logo após o bloco doFirst , manualmente.

doFirst { ... }
doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
            ant.move(file: originalDir, tofile: destDir);
        }
    }
    moveFunc.curry("ldpi").call()
    moveFunc.curry("mdpi").call()
    moveFunc.curry("hdpi").call()
    moveFunc.curry("xhdpi").call()
    moveFunc.curry("xxhdpi").call()
    moveFunc.curry("xxxhdpi").call()
}

Todos 103 comentários

verifique este https://github.com/facebook/react-native/issues/19239#issuecomment -414564404

Você precisa remover a imagem da pasta drawable, se houver alguma?

@ ZeroCool00 não vai afetar as imagens no Android?

A resposta do Mapsy deve ajudar https://stackoverflow.com/a/52750886
Basicamente, você edita o arquivo /node_modules/react-native/react.gradle
e adicione o doLast logo após o bloco doFirst , manualmente.

doFirst { ... }
doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
            ant.move(file: originalDir, tofile: destDir);
        }
    }
    moveFunc.curry("ldpi").call()
    moveFunc.curry("mdpi").call()
    moveFunc.curry("hdpi").call()
    moveFunc.curry("xhdpi").call()
    moveFunc.curry("xxhdpi").call()
    moveFunc.curry("xxxhdpi").call()
}

@ ZeroCool00 @mkchx Eu verifiquei sua resposta, está funcionando. Muito obrigado pessoal :)

Olá a todos, como podemos fazer isso com o trabalho de Jenkins Como ele fará, o npm instalará sempre que substituirá essa alteração no arquivo react.gradle. Podemos criar build no Android Studio para Android, mas não é possível no Jenkins.

Olá @ vivek-walecha-657, não tentei isso, mas você pode tentar este comando para criar empacotamento offline

react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle

@jeffreyrajanofficial Obrigado por escrever, a solução que você forneceu ajudará se mudarmos o arquivo react.gradle. Mas não quero fazer o lançamento alterando o arquivo react.gradle toda vez que instalo o npm em qualquer lugar.

@jeffreyrajanofficial Você pode dizer qual versão (a mais recente, inferior ou superior) está funcionando bem, sem esse problema. Porque as notas de lançamento não dizem nada que este problema foi resolvido.

As coisas são classificadas agora no arquivo RN> 57 react.gradle cria automaticamente o pacote.
para criar uma versão de lançamento, você não precisa executar o npm run build: android : release

Usando a versão nativa da reação 55.4, aqui está a essência do meu projeto de amostra para build.gradle package.json com correções.

https://gist.github.com/Abhishekgarg727/daf031fb9f94fdfd985e84db57dedbe1

Eu ainda estava vendo isso, usando o macOS 10.14.3 + RN 0.57.8 + Android Studio 3.3 + Gradle 4.10.3. Talvez eu não seja o único? Ou talvez alguém aqui possa confirmar que funciona, então vou cavar mais e consertar para mim mesmo.

No momento, estou trabalhando nisso com o pacote "patch-package" em combinação com o patch anexado com base no comentário acima de @mkchx (com .txt sufixo anexado para que o github aceite o anexo) para automagicamente conserte em 'npm install' depois de adicionar postinstall: patch-package aos meus scripts package.json.

Talvez isso seja útil para alguém ...
react-native + 0.57.8.patch.txt

Remova os arquivos que você pode ter em:

android / app / src / main / res / drawable-mdpi /
android / app / src / main / res / drawable-xhdpi /
android / app / src / main / res / drawable-xxhdpi /
Execute o Build novamente. Isso corrigiu o problema para mim.

Eu ainda estava vendo isso em RN0.58.xe continua em RN0.59.x - estamos fazendo algo errado aqui ou é realmente um bug?

Eu continuo tendo sucesso com a solução alternativa de @mkchx codificado em forma de patch no diretório de patches para uso com o módulo patch-package e este patch (atualizado para RN0.59.1)

react-native + 0.59.1.patch.txt

Se você tiver recursos extras adicionados em pastas personalizadas, pode tentar algo assim:

doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("$buildDir/generated/res/react/release/${resSuffix}");
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/${resSuffix}");
            ant.move(file: originalDir, tofile: destDir);
        }
    }
    moveFunc.curry("drawable-ldpi").call()
    moveFunc.curry("drawable-mdpi").call()
    moveFunc.curry("drawable-hdpi").call()
    moveFunc.curry("drawable-xhdpi").call()
    moveFunc.curry("drawable-xxhdpi").call()
    moveFunc.curry("drawable-xxxhdpi").call()
    moveFunc.curry("raw").call()
}

Mas se você tiver dependências que empacotam seus próprios ativos, isso não está funcionando, ainda recebendo este erro (editado para maior clareza):

Execution failed for task ':app:mergeReleaseResources'.

> [drawable-xxxhdpi-v4/node_modules_reactnavigationstack_dist_views_assets_backicon] 
/[...]/android/app/src/main/res/drawable-xxxhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png

[drawable-xxxhdpi-v4/node_modules_reactnavigationstack_dist_views_assets_backicon] 
/[...]/android/app/build/generated/res/react/release/drawable-xxxhdpi/node_modules_reactnavigationstack_dist_views_assets_backicon.png: 

Error: Duplicate resources

Isso é avaliado ativamente ou devemos seguir em frente com nossos próprios patches?

@dragosroua Vejo um hífen faltando em seu curry xxxhdpi. Coincidentemente, os mesmos caminhos principais com problemas para você?

Você me venceu por 2 minutos, eu estava prestes a editar essa parte. Sim, tudo se agrupa bem agora, mas a parte com o caminho "bruto" para recursos personalizados pode ser útil para alguém.

@dragosroua que bom que você está compilando agora - lembro como esse foi frustrante para mim, e ainda estou surpreso que não tenha sido corrigido no master, embora eu não tenha proposto um PR também, então acho que consegui o que coloquei. ..

Eu ainda estava vendo isso, usando o macOS 10.14.3 + RN 0.57.8 + Android Studio 3.3 + Gradle 4.10.3. Talvez eu não seja o único? Ou talvez alguém aqui possa confirmar que funciona, então vou cavar mais e consertar para mim mesmo.

No momento, estou trabalhando nisso com o pacote "patch-package" em combinação com o patch anexado com base no comentário acima de @mkchx (com .txt sufixo anexado para que o github aceite o anexo) para automagicamente conserte em 'npm install' depois de adicionar postinstall: patch-package aos meus scripts package.json.

Talvez isso seja útil para alguém ...
react-native + 0.57.8.patch.txt

Por favor, me explique por que para o meu 0.57.5 nativo reagente não funciona?
Eu criei o arquivo pacth. Adicionado ao package.json. Execute npm install e tem como resultado

        def currentBundleTask = tasks.create(
            name: "bundle${targetName}JsAndAssets",
            type: Exec) {
            group = "react"
            description = "bundle JS and assets for ${targetName}."

            // Create dirs if they are not there (e.g. the "clean" task just ran)
            doFirst {
                jsBundleDir.deleteDir()
                jsBundleDir.mkdirs()
                resourcesDir.deleteDir()
                resourcesDir.mkdirs()
            }

            // Set up inputs and outputs so gradle can cache the result
            inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
            outputs.dir jsBundleDir
            outputs.dir resourcesDir

sem mudanças necessárias.

@zakabluk, você precisa postar a saída de sua instalação do npm, mas como um palpite é porque o pacote patch-package é muito cuidadoso com os números de versão. você está tentando em 57.5, mas o patch é contra 57.8?

Eu geralmente faço scripts python para patching node_modules.
Adicione isso como postinstall.py e adicione-o ao seu script de pós-instalação ou execute-o com ./postinstall.py

#!/usr/bin/env python3

import os
import textwrap

def file_dir():
  return os.path.dirname(os.path.realpath(__file__))

def read_file(filename):
    '''
    Reads the specified file.

    :param filename: The file to read
    :return: The content of the specified file
    '''
    if os.path.exists(filename):
        with open(filename, "r") as file:
            return file.read()
    else:
        raise IOError("file {} not found.".format(filename))

def write_file(filename, text):
    '''
    Writes the specified text to the specified file.

    :param filename: The file to write to
    :param text: The text to write
    '''
    with open(filename, "w") as file:
        file.write(text)

def fix_android_assets():
  print("Fixing android error with duplicate assets: https://github.com/facebook/react-native/issues/22234")

  gradle_file_path = "{}/node_modules/react-native/react.gradle".format(file_dir())

  code_snippet = textwrap.indent("""\
            // Added by post_install
            // Fix for: https://github.com/facebook/react-native/issues/22234
            doLast {
                def moveFunc = { resSuffix ->
                    File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
                        ant.move(file: originalDir, tofile: destDir);
                    }
                }
                moveFunc.curry("ldpi").call()
                moveFunc.curry("mdpi").call()
                moveFunc.curry("hdpi").call()
                moveFunc.curry("xhdpi").call()
                moveFunc.curry("xxhdpi").call()
                moveFunc.curry("xxxhdpi").call()
            }
  """, "")

  text = read_file(gradle_file_path)

  start = text.find("doFirst", 0)
  end = text.find("}", start)
  end = text.find("\n", end) + 1

  text = text[:end] + code_snippet + text[end:]

  write_file(gradle_file_path, text)

def main():
    fix_android_assets()

if __name__ == "__main__":
    main()

Aqui você pode adicionar seus próprios scripts, se necessário

Parece uma reimplementação do que você obtém com npm install patch-package mas se você gosta de python e deseja manter mais código, isso parece viável. Ainda estou usando patch-package pelo que vale a pena, com 0.59.3 assim
react-native + 0.59.3.patch.txt

@hramos - # 19239 era semelhante (eu acho) e isso é antigo, mas parece ter uma correção. Isso só precisa de um PR para uma correção final ou estou perdendo um motivo pelo qual o patch usado aqui não é viável? (Eu posso ser). Se apenas precisarmos de um PR, posso enviar um ...

Parece uma reimplementação do que você obtém com npm install patch-package mas se você gosta de python e deseja manter mais código, isso parece viável. Ainda estou usando patch-package pelo que vale a pena, com 0.59.3 assim
react-native + 0.59.3.patch.txt

@hramos - # 19239 era semelhante (eu acho) e isso é antigo, mas parece ter uma correção. Isso só precisa de um PR para uma correção final ou estou perdendo um motivo pelo qual o patch usado aqui não é viável? (Eu posso ser). Se apenas precisarmos de um PR, posso enviar um ...

Como usar este caminho, obrigado

@ZhanRu - https://github.com/ds300/patch-package#set -up - você apenas deseja colocar esse patch (com extensão .patch) no diretório 'patches' em seu projeto após instalar e configurar o patch- pacote

@ZhanRu - https://github.com/ds300/patch-package#set -up - você apenas deseja colocar esse patch (com extensão .patch) no diretório 'patches' em seu projeto após instalar e configurar o patch- pacote

Muito obrigado

Para quem ainda está acompanhando, recentemente integrei um sistema externo e precisei separar meu teste dos dados externos de produção, o que leva ao uso de "sabores" no gradle para que você possa ter qaDebug, stagingRelease, etc etc apontando para um sistema externo diferente. O patch aqui não oferece suporte para isso, então eu adicionei o suporte para sabores, e meu patch está assim agora. Vive em patches/react-native+0.59.5.patch onde é aplicado durante npm i corridas após npm install patch-package

diff --git a/node_modules/react-native/react.gradle b/node_modules/react-native/react.gradle
index 4ead2b6..e0f92b7 100644
--- a/node_modules/react-native/react.gradle
+++ b/node_modules/react-native/react.gradle
@@ -48,6 +48,33 @@ afterEvaluate {
                 resourcesDir.mkdirs()
             }

+            // From https://stackoverflow.com/questions/53239705/react-native-error-duplicate-resources-android
+            // Currently has no solution?
+
+            // IF you are using flavors, add flavor name to the path you move from
+            def flavorPathSegment = ""
+            android.productFlavors.all { flavor ->
+                if (targetName.toLowerCase().contains(flavor.name)) {
+                    flavorPathSegment = flavor.name + "/"
+                }
+            }
+
+            doLast {
+                def moveFunc = { resSuffix ->
+                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}")
+                    if (originalDir.exists()) {
+                        File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
+                        ant.move(file: originalDir, tofile: destDir);
+                    }
+                }
+                moveFunc.curry("ldpi").call()
+                moveFunc.curry("mdpi").call()
+                moveFunc.curry("hdpi").call()
+                moveFunc.curry("xhdpi").call()
+                moveFunc.curry("xxhdpi").call()
+                moveFunc.curry("xxxhdpi").call()
+            }
+
             // Set up inputs and outputs so gradle can cache the result
             inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
             outputs.dir(jsBundleDir)

No meu caso, o problema persiste com o diretório raw .

Versão: react-native 0.59.5

Minha solução:

doLast {                                                                                            
  def moveFunc = { resSuffix ->                                                                   
    File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");     
    if (originalDir.exists()) {                                                                 
      File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");                 
      ant.move(file: originalDir, tofile: destDir);                                           
    }
  } 
  def moveRawFunc = { dir ->                                                                   
    File originalDir = file("$buildDir/generated/res/react/release/${dir}");     
    if (originalDir.exists()) {                                                                 
      File destDir = file("$buildDir/../src/main/res/${dir}");                 
      ant.move(file: originalDir, tofile: destDir);                                           
    }
  }  
  moveFunc.curry("ldpi").call()
  moveFunc.curry("mdpi").call()
  moveFunc.curry("hdpi").call()
  moveFunc.curry("xhdpi").call()
  moveFunc.curry("xxhdpi").call()
  moveFunc.curry("xxxhdpi").call()
  moveRawFunc.curry("raw").call()
}

Saudações

@Dbroqua sua solução funcionou para mim (versão react-native 0.59.5 ). Obrigado.

Muito interessante - não tive problemas com o raw - esteja ciente de que minha versão mais recente do patch adicionou suporte para sabores. Se você começar a fazer sabores, você vai querer esse suporte a sabores agora em ambas as funções. Talvez pudesse ser parametrizado de alguma forma para que as 2 funções não sejam tão repetitivas, mas não sou bom o suficiente no groovy para contemplar isso.

Só posso imaginar que isso não seja um problema no Facebook e em CI reagente nativo porque eles estão usando o BUCK e seus builds de CI sempre limpos. Alguém tem uma reprodução limpa disso para que possamos corrigir o problema upstream?

No meu caso, o diretório bruto contém alguns mp3 usados ​​em meu aplicativo.

Isso pode formar a base de uma reprodução rápida + fácil. Não tenho ativos como esse (ainda), mas é fácil o suficiente para reativar o init nativo para um repo, coloque alguns ativos, então acho que na segunda versão do build (talvez até o primeiro?) Você está hosed ...

@Dbroqua só para

Está bem,

Eu farei o necessário o mais rápido possível.

Saudações,
Damien

Fixo!

No meu caso, havia arquivos nos diretórios drawables res/drawable-* remanescentes de algum outro desenvolvedor do commit de minha equipe - estava recebendo um "Erro: recursos duplicados" apontando para esses nomes de arquivo - excluí os arquivos dos drawables e tudo funciona bem 👍

A resposta do Mapsy deve ajudar https://stackoverflow.com/a/52750886
Basicamente, você edita o arquivo /node_modules/react-native/react.gradle
e adicione o doLast logo após o bloco doFirst , manualmente.

doFirst { ... }
doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
            ant.move(file: originalDir, tofile: destDir);
        }
    }
    moveFunc.curry("ldpi").call()
    moveFunc.curry("mdpi").call()
    moveFunc.curry("hdpi").call()
    moveFunc.curry("xhdpi").call()
    moveFunc.curry("xxhdpi").call()
    moveFunc.curry("xxxhdpi").call()
}

não está funcionando para mim.

@ Nextt1, você precisará abrir um novo problema - com um caso de teste reproduzível em um repositório público, se possível - e talvez propor um novo PR. Este problema foi resolvido pelo meu PR e, em seguida, outro (lidando com um caso que meu primeiro PR não lidou bem) também foi mesclado, então todos nós mudamos e acho que está funcionando para a maioria, então esse problema não é provável atenção.

Olá a todos - o PR que propus corrigir isso foi mesclado, mas aparentemente causa uma regressão - https://github.com/facebook/react-native/issues/25325 - Estou investigando, mas se há algum gurus do Gradle aqui que agora como corrigir esse problema sem causar essa regressão, agradecemos a ajuda - obrigado!

Ok, o PR relacionado aqui terá um "PR de reversão" - ele causa uma regressão, e o problema subjacente que causou esse problema era, na verdade, uma documentação ruim.

É o seguinte: você nunca deve copiar coisas para o diretório src durante uma construção. Você precisa copiar coisas em intermediários e gerado etc. Se você já copiou coisas em src (de compilações anteriores usando este patch, ou de um comando do bundle react-native): você precisa limpar isso para seu src / main / res diretório está limpo - apenas ativos reais de seu projeto

Agora, para construir um APK com um pacote offline - mesmo em dev para que você possa executá-lo na API <17, você deve fazer as coisas de forma diferente do que todos na web recomendam (ou você terá esse problema).

O que você quer é isso em seu android/app/build.gradle :

project.ext.react = [

        // This is what most people will need
        bundleInDebug: project.hasProperty("bundleInDebug") ? project.getProperty("bundleInDebug") : false,

        // If you use build variants it has to be like this - put your own names in there
        bundleInDevDebug: project.hasProperty("bundleInDevDebug") ? project.getProperty("bundleInDevDebug") : false,
        bundleInQaDebug: project.hasProperty("bundleInQaDebug") ? project.getProperty("bundleInQaDebug") : false,
        bundleInStagingDebug: project.hasProperty("bundleInStagingDebug") ? project.getProperty("bundleInStagingDebug") : false,
        bundleInProdDebug: project.hasProperty("bundleInProdDebug") ? project.getProperty("bundleInProdDebug") : false
]

Em seguida, você chama react-native algo assim - enviando uma propriedade do projeto gradle por meio de uma variável de ambiente:
ORG_GRADLE_PROJECT_bundleInDebug=true npx react-native run-android

(ou para variantes como este ORG_GRADLE_PROJECT_bundleInDevDebug=true npx react-native run-android --variant devDebug )

Eu ainda estava vendo isso, usando o macOS 10.14.3 + RN 0.57.8 + Android Studio 3.3 + Gradle 4.10.3. Talvez eu não seja o único? Ou talvez alguém aqui possa confirmar que funciona, então vou cavar mais e consertar para mim mesmo.

No momento, estou trabalhando nisso com o pacote "patch-package" em combinação com o patch anexado com base no comentário acima de @mkchx (com .txt sufixo anexado para que o github aceite o anexo) para automagicamente conserte em 'npm install' depois de adicionar postinstall: patch-package aos meus scripts package.json.

Talvez isso seja útil para alguém ...
react-native + 0.57.8.patch.txt

Impressionante! Por enquanto, é a melhor resposta!

Ainda estou vendo isso em 0.59.9. A resposta de @mkchx resolveu o problema para mim

@juliancorrea @scgough tome cuidado com isso, segui esse estilo de solução até o fim com um PR até aceito, mas depois de problemas posteriores tivemos que revertê-lo. É uma solução sem saída. Postei detalhes completos da solução atualmente recomendada alguns comentários acima e só posso recomendar o novo estilo. Se você usar meu antigo patch anexado com base na resposta @mkchx, ele funcionará para você, por enquanto, mas apenas sob certas condições - ele falha em outros cenários comuns que seu projeto pode precisar no futuro

@mikehardy OK - examinarei sua solução agora.
Eu _penso_ o que realmente quero é que a construção do APK assinado do Android Studio ignore o pacote (já que faço isso manualmente através do terminal).
Vou dar uma olhada nas configurações que você forneceu e ver se elas ajudam.

Ainda estou tendo problemas com isso ...
Não consigo criar meu arquivo APK de lançamento. Recebo o seguinte erro para cada arquivo de ativo:

[drawable-mdpi-v4/filename] /Users/me/React/myapp/android/app/src/main/res/drawable-mdpi/filename.png
[drawable-mdpi-v4/filename] /Users/me/React/myapp/android/app/build/generated/res/react/release/drawable-mdpi/filename.png : Erro: recursos duplicados

Excluí as duas instâncias das pastas drawable-mdpi mas a geração do APK as devolve e apresenta erros.
Estou executando o seguinte manualmente para criar meu pacote:

react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/

No meu gradle de aplicativo eu tenho:

project.ext.react = [
    entryFile: "index.android.js",
    bundleInRelease: true    //I've tried true and false here
]

apply from: "../../node_modules/react-native/react.gradle"

Como informação extra - meu aplicativo funciona bem na depuração (via react-native run-android )
No momento, a única maneira de fazer meu APK de lançamento construir é por meio da correção de PR revertida doLast acima.

Acho que pelo menos tenho o motivo / solução para o meu problema.

Meu comando de pacote antigo (eu uso desde RN 0.2.x ?!) enviou os ativos para a pasta de destino android/app/src/main/res/

Observei uma postagem no link abaixo que afirma que> RN 57 realmente precisa de ativos enviados para a seguinte pasta:
android/app/build/intermediates/res/merged/release/

Fonte: https://github.com/facebook/react-native/issues/19211#issuecomment -448301870

Eu fiz o seguinte:

  • excluiu os drawable-mdpi ativos que foram copiados para android/app/src/main/res/
  • atualizou o comando do meu pacote para usar o novo local da pasta
  • meu APK agora constrói ... (_ Estou prestes a testá-lo_)

atualizar
O APK foi instalado, mas o aplicativo trava agora com a exceção:
com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'defaultSrc' of a view managed by: RCTImageView

... então parece que não consegue encontrar as imagens 😞

atualização 2
A única maneira de fazer o APK funcionar (até agora) é fazer o seguinte:

  • reverter minha chamada de pacote para usar o seguinte para ativos: android/app/src/main/res/
  • execute o comando bundle
  • renomeie android/app/src/main/res/drawable-mdpi para android/app/src/main/res/drawable-hdpi
  • construir o APK assinado

meu gradle de construção é:

project.ext.react = [
    entryFile: "index.android.js"
]

O APK então é compilado e executado ...

Nota:
Eu recebi um bug inesperado resultando em uma exceção createBitmap OutOfMemory em um componente deslizante de imagem.
Adicionei o seguinte ao meu manifesto e o aplicativo é executado novamente: android:largeHeap="true"
Estou ciente de que a adição está contornando o que poderia ser um problema de vazamento / componente, mas até agora o aplicativo é executado sem problemas novamente.

No React Native 0.60.0, percebi que a base nativa também está criando recursos duplicados, mas a solução alternativa acima não funcionará porque tem como objetivo a pasta bruta.

[raw / node_modules_nativebase_dist_src_basic_icon_nbicons] C: \ Projects \ some-app \ CLIENT \ android \ app \ src \ main \ resrawnode_modules_nativebase_dist_src_basic_icon_nbicons.json
[raw / node_modules_nativebase_dist_src_basic_icon_nbicons] C: \ Projects \ some-app \ CLIENT \ android \ app \ build \ generated \ res \ reactreleaserawnode_modules_nativebase_dist_src_basic_icon_nbicons.json: Erro: recursos duplicados

Para outros usuários com este problema:

        doLast {
            def moveFunc = { resSuffix ->
                File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
                if (originalDir.exists()) {
                    File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
                    ant.move(file: originalDir, tofile: destDir);
                }
            }

            moveFunc.curry("ldpi").call()
            moveFunc.curry("mdpi").call()
            moveFunc.curry("hdpi").call()
            moveFunc.curry("xhdpi").call()
            moveFunc.curry("xxhdpi").call()
            moveFunc.curry("xxxhdpi").call()

            File originalDir = file("$buildDir/generated/res/react/release/raw");
                if (originalDir.exists()) {
                    File destDir = file("$buildDir/../src/main/res/raw");
                    ant.move(file: originalDir, tofile: destDir);
            }
        }

como podemos resolver isso se estamos usando CI?

No meu caso, o problema persiste com o diretório raw .

Versão: react-native 0.59.5

Minha solução:

doLast {                                                                                            
  def moveFunc = { resSuffix ->                                                                   
    File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");     
    if (originalDir.exists()) {                                                                 
      File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");                 
      ant.move(file: originalDir, tofile: destDir);                                           
    }
  } 
  def moveRawFunc = { dir ->                                                                   
    File originalDir = file("$buildDir/generated/res/react/release/${dir}");     
    if (originalDir.exists()) {                                                                 
      File destDir = file("$buildDir/../src/main/res/${dir}");                 
      ant.move(file: originalDir, tofile: destDir);                                           
    }
  }  
  moveFunc.curry("ldpi").call()
  moveFunc.curry("mdpi").call()
  moveFunc.curry("hdpi").call()
  moveFunc.curry("xhdpi").call()
  moveFunc.curry("xxhdpi").call()
  moveFunc.curry("xxxhdpi").call()
  moveRawFunc.curry("raw").call()
}

Saudações

Isso funciona!

[drawable-mdpi-v4/node_modules_reactnativemaplink_src_images_uber] /Users/umair/my-app/android/app/src/main/res/drawable-mdpi/node_modules_reactnativemaplink_src_images_uber.png   [drawable-mdpi-v4/node_modules_reactnativemaplink_src_images_uber] /Users/umair/my-app/android/app/build/generated/res/react/debug/drawable-mdpi/node_modules_reactnativemaplink_src_images_uber.png: Error: Duplicate resources

Recebo este erro quando executo react-native run-android mas não quando construo e executo a versão de lançamento. Nenhuma das soluções acima funciona para mim.

RN 0.60.5

ATUALIZAÇÃO: percebi que deveria modificar os métodos de "patch" acima para citar os diretórios debug vez de release e isso corrigiu. Eu também tive que consertar meu diretório raw

Eu também estou tendo o mesmo problema e o patch react.gradle não vai resolver isso. No meu caso, meus recursos duplicados são arquivos .OBJ e .MTL, não tenho problemas com recursos de imagem.

[raw / assets_res_salad_salad] /Users/sercanov/Projects/ARt/diner/DinerApp/android/app/src/main/res/raw/assets_res_salad_salad.mtl [raw / assets_res_salad_salad] / Users / sercanov / Projects / ARt / diner / DinerApp /android/app/src/main/res/raw/assets_res_salad_salad.obj: Erro: recursos duplicados
[raw / assets_res_steak_steak] /Users/sercanov/Projects/ARt/diner/DinerApp/android/app/src/main/res/raw/assets_res_steak_steak.mtl [raw / assets_res_steak_steak] / Users / sercanov / Projects / ARt / diner / DinerApp /android/app/src/main/res/raw/assets_res_steak_steak.obj: Erro: recursos duplicados
[raw / assets_res_salmon_salmon] /Users/sercanov/Projects/ARt/diner/DinerApp/android/app/src/main/res/raw/assets_res_salmon_salmon.mtl [raw / assets_res_salmon_salmon] / Users / sercanov / Projects / ARt / diner / DinerApp /android/app/src/main/res/raw/assets_res_salmon_salmon.obj: Erro: recursos duplicados

@sercanov você ainda está tentando usar a cópia para src? Esse estilo foi investigado e falha por razões conhecidas. Existem maneiras de construir que não colocam as coisas em src - ou você está tentando essas maneiras de não copiar em src e ainda falhando? https://github.com/facebook/react-native/issues/22234#issuecomment -504721069

hey @mikehardy realmente tentou ambas as abordagens, nenhuma delas funcionou em compilações de lançamento. Ele funciona bem no modo de depuração btw.

Ao usar o método not-copy-to-src ORG_GRADLE_PROJECT_bundleInArRelease=true npx react-native run-android --variant arRelease estou recebendo este;

A execução falhou para a tarefa ': app: mergeArReleaseResources '.
[raw / assets_res_salad_salad] /Users/sercanov/Projects/ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_salad_salad.mtl [raw / assets_res_salad_salad] / Users / sercanov / /ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_salad_salad.obj: Erro: recursos duplicados
[raw / assets_res_steak_steak] /Users/sercanov/Projects/ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_steak_steak.mtl [raw / assets_res_steak_steak] / Users / sercanov / /ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_steak_steak.obj: Erro: recursos duplicados
[raw / assets_res_salmon_salmon] /Users/sercanov/Projects/ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_salmon_salmon.mtl [raw / assets_res_salmon_salmon] / Projects / sercanov / /ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_salmon_salmon.obj: Erro: recursos duplicados

Quando usado o modo doLast copy-to-src; Eu tive que limpar a pasta android / build sempre que eu construí para torná-la bem-sucedida, mas de alguma forma os ativos não estavam disponíveis no aplicativo. Isso pode estar relacionado ao meu código, atualmente investigando sobre isso.

Ao mudar para o modo não copiar para src, você deve limpar tudo primeiro, para fazer a mudança. Meu projeto tinha muito "lixo" de uma perspectiva de empacotamento do estilo anterior de cópia para src que eu tive que limpar antes de funcionar, então funcionou sempre.

@ rahulkumar1409 isso me ajudou neste erro, mas gera outro erro

Tarefa : react -native-simple-download-

Você tem alguma ideia do porquê isso aconteceu ??

Essa solução funcionou para mim.
Basicamente, você edita o arquivo /node_modules/react-native/react.gradle
e adicione o doLast logo após o bloco doFirst, manualmente.

faça primeiro { ... }
doLast {
def moveFunc = {resSuffix ->
Arquivo originalDir = arquivo ("$ buildDir / gerado / res / react / release / drawable - $ {resSuffix}");
if (originalDir.exists ()) {
Arquivo destDir = arquivo ("$ buildDir /../ src / main / res / drawable - $ {resSuffix}");
ant.move (arquivo: originalDir, tofile: destDir);
}
}
moveFunc.curry ("ldpi"). call ()
moveFunc.curry ("mdpi"). call ()
moveFunc.curry ("hdpi"). call ()
moveFunc.curry ("xhdpi"). call ()
moveFunc.curry ("xxhdpi"). call ()
moveFunc.curry ("xxxhdpi"). call ()
}

Estamos em 0,60.5 nativo reagente.

Estamos usando versões de produtos como @Dbroqua experimentou.

Acabei misturando as duas soluções e usamos este código:

doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}")
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
            ant.move(file: originalDir, tofile: destDir)
        }
    }
    def moveRawFunc = { dir ->
        File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/${dir}")
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/${dir}")
            ant.move(file: originalDir, tofile: destDir)
        }
    }

    moveFunc.curry("ldpi").call()
    moveFunc.curry("mdpi").call()
    moveFunc.curry("hdpi").call()
    moveFunc.curry("xhdpi").call()
    moveFunc.curry("xxhdpi").call()
    moveFunc.curry("xxxhdpi").call()
    moveRawFunc.curry("raw").call()
}

Este tópico tem sido muito útil, obrigado a todos por contribuir. 😄

Estou recebendo o erro duplicado apenas em compilações de lançamento. Estou usando 60,5 nativo de reação

/release/drawable-xhdpi/node_modules_reactnavigationstack_lib_module_views_assets_backicon.png: Erro: recursos duplicados

Tentei definir bundleInDebug como true e false, mas sem efeito.

Estou construindo usando o app center, isso requer um arquivo src / main / assets / appcenter-config.json. Eu também tenho um diretório src / main / assets / fonts porque estou usando fontes personalizadas. É provável que isso esteja causando o problema?

@ARichIVC Suponho que o problema seja o arquivo mencionado em sua mensagem de erro.

Parece que o problema padrão "meu diretório / src está poluído de tentativas anteriores de copiar para lidar com o pacote de pacotes" desta solução original antes de todos percebermos que é uma solução sem saída e você precisa limpar src / fora dos copiados antes de tentar a solução subsequente de fazer as coisas do bundleInDebug. Está tudo neste tópico que infelizmente é longo e pesado, mas a informação está lá

Obrigado @mikehardy por sua ajuda. Achei que não havia problema em deixar as fontes, etc, no diretório de recursos, mas precisei excluir os outros bits e peças pendentes. Ou seja, tudo em \ android \ app \ src \ main \ res \ drawable-hdpi \

Observe que mesmo para fontes, elas devem estar no diretório certo - um exemplo: https://github.com/oblador/react-native-vector-icons#android que o direciona a chamar este arquivo que copia cuidadosamente em um não-src diretório https://github.com/oblador/react-native-vector-icons/blob/master/fonts.gradle#L16 - o projeto de cada um é diferente, claro, mas achei que valeria a pena mencionar

Estamos em 0,60.5 nativo reagente.

Estamos usando versões de produtos como @Dbroqua experimentou.

Acabei misturando as duas soluções e usamos este código:

doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}")
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
            ant.move(file: originalDir, tofile: destDir)
        }
    }
    def moveRawFunc = { dir ->
        File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/${dir}")
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/${dir}")
            ant.move(file: originalDir, tofile: destDir)
        }
    }

    moveFunc.curry("ldpi").call()
    moveFunc.curry("mdpi").call()
    moveFunc.curry("hdpi").call()
    moveFunc.curry("xhdpi").call()
    moveFunc.curry("xxhdpi").call()
    moveFunc.curry("xxxhdpi").call()
    moveRawFunc.curry("raw").call()
}

Este tópico tem sido muito útil, obrigado a todos por contribuir. 😄

funciona! muito obrigado! 👍

Para react Native 0.59.1 ou superior, você precisa adicionar o código abaixo em react.gradle em node_modules / react-native.

para uso com sabor abaixo do código.

        def flavorPathSegment = ""
        android.productFlavors.all { flavor ->
            if (targetName.toLowerCase().contains(flavor.name)) {
                flavorPathSegment = flavor.name
           }
        }
        doLast {
            def moveFunc = { resSuffix ->
                File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}/release/drawable-${resSuffix}");
                if (originalDir.exists()) {
                    File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
                    ant.move(file: originalDir, tofile: destDir);
                }
            }
            moveFunc.curry("ldpi").call()
            moveFunc.curry("mdpi").call()
            moveFunc.curry("hdpi").call()
            moveFunc.curry("xhdpi").call()
            moveFunc.curry("xxhdpi").call()
            moveFunc.curry("xxxhdpi").call()
        }

@ dayachand-systemmatix este conselho ruim. Essa solução de estilo foi perseguida a ponto de ter uma RP e até mesmo ser fundida. Então descobriu-se que estava na direção errada e o PR foi revertido. Você aconselharia as pessoas a usarem uma solução que realmente causou a reversão de uma fusão de RP? Eu não faria. https://github.com/facebook/react-native/issues/22234#issuecomment -504721069

@mikehardy Sim, eu sei que esta não é uma solução permanente, mas está funcionando bem. E também não consigo usar sua solução porque tenho alguns outros arquivos, como telas de abertura e DB no diretório res .

Sim @ dayachand-sistematix me também:

mike<strong i="6">@isabela</strong>:~/work/Kullki/ksocialscore/packages/public-app/android/app (lerna-import) % find . -type f |grep res
./src/main/res/drawable-xhdpi/minilogo_bw.png
./src/main/res/mipmap-xxhdpi/ic_launcher.png
./src/main/res/values-v21/styles.xml
./src/main/res/drawable-xxhdpi/minilogo_bw.png
./src/main/res/drawable-xxhdpi/kscore_splash.png
./src/main/res/drawable-hdpi/minilogo_bw.png
./src/main/res/mipmap-xxxhdpi/ic_launcher.png
./src/main/res/mipmap-hdpi/ic_launcher.png
./src/main/res/layout/launch_screen.xml
./src/main/res/drawable/background_launch.xml
./src/main/res/values/colors.xml
./src/main/res/values/styles.xml
./src/main/res/values/strings.xml
./src/main/res/mipmap-xhdpi/ic_launcher.png
./src/main/res/xml/filepaths.xml
./src/main/res/xml/react_native_config.xml
./src/main/res/drawable-mdpi/minilogo_bw.png
./src/main/res/drawable-xxxhdpi/minilogo_bw.png
./src/main/res/mipmap-mdpi/ic_launcher.png
./src/qa/res/mipmap-xxhdpi/ic_launcher.png
./src/qa/res/mipmap-xxxhdpi/ic_launcher.png
./src/qa/res/mipmap-hdpi/ic_launcher.png
./src/qa/res/values/strings.xml
./src/qa/res/mipmap-xhdpi/ic_launcher.png
./src/qa/res/mipmap-mdpi/ic_launcher.png
./src/debug/res/xml/react_native_config.xml
./src/staging/res/mipmap-xxhdpi/ic_launcher.png
./src/staging/res/mipmap-xxxhdpi/ic_launcher.png
./src/staging/res/mipmap-hdpi/ic_launcher.png
./src/staging/res/values/strings.xml
./src/staging/res/mipmap-xhdpi/ic_launcher.png
./src/staging/res/mipmap-mdpi/ic_launcher.png
./src/dev/res/mipmap-xxhdpi/ic_launcher.png
./src/dev/res/mipmap-xxxhdpi/ic_launcher.png
./src/dev/res/mipmap-hdpi/ic_launcher.png
./src/dev/res/values/strings.xml
./src/dev/res/mipmap-xhdpi/ic_launcher.png
./src/dev/res/mipmap-mdpi/ic_launcher.png

E ainda assim a solução sugerida / não revertida no PR funciona para mim: man_shrugging:

Ei, nós consertamos removendo o parâmetro --asset-dest :

react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle

@ hery-finimize hi - não removeria o parâmetro --asset-dest resultaria em que os recursos mais recentes não fossem agrupados no local correto ... então, quando você criar seu APK, haveria o perigo de perder / perder data arquivos de ativos no aplicativo?

@scgough , imaginei que poderia ser o caso. Nesse caso, podemos remover seletivamente todos os ativos duplicados, exceto os ativos locais de que precisamos antes de construir com o Android Studio ou qualquer outro fluxo de trabalho de produção, por exemplo,

find android/app/src/main/res/drawable-* \( -name launch_screen.png -o -name ic_stat_onesignal_default.png -prune \) -o -type f -exec rm {} +

Não é o ideal, mas deve funcionar até que isso seja resolvido.

Este problema é causado quando você tem arquivos de mesmo nome e extensão diferente na pasta de ativos como essa

back.png
back.jpg

porque no android os dois estão chamando assim;

R.drawable.back
R.drawable.back

remova ou renomeie um dos arquivos.

Oi,
Tentei modificar o react.gradle: a compilação vai um passo além (o app.aab é uma compilação, mas não consigo compilar o APK.

Tentei construir o APK com o Android Studio e não houve problema (com o patch para react.gradle).
É muito estranho para mim porque o processo de construção do APK deve ser o mesmo em ambos os casos. Estou errado ?

Este comentário funcionou para 0.59.10. Misturado com esta essência .

Muito obrigado, @ dayachand-sistemamatix!

O que funcionou para mim foi uma combinação de dois comentários:

Estou colando isso aqui para qualquer pessoa que possa precisar.

`` `
def flavourPathSegment = ""
android.productFlavors.all {flavour ->
if (targetName.toLowerCase (). contains (flavour.name)) {
flavourPathSegment = flavour.name
}
}

        doLast {
            def moveFunc = { resSuffix ->
                File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}")
                if (originalDir.exists()) {
                    File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
                    ant.move(file: originalDir, tofile: destDir)
                }
            }
            def moveRawFunc = { dir ->
                File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/${dir}")
                if (originalDir.exists()) {
                    File destDir = file("$buildDir/../src/main/res/${dir}")
                    ant.move(file: originalDir, tofile: destDir)
                }
            }

            moveFunc.curry("ldpi").call()
            moveFunc.curry("mdpi").call()
            moveFunc.curry("hdpi").call()
            moveFunc.curry("xhdpi").call()
            moveFunc.curry("xxhdpi").call()
            moveFunc.curry("xxxhdpi").call()
            moveRawFunc.curry("raw").call()
        }

@AbhishekNairOfficial onde você coloca isso?

@AbhishekNairOfficial onde você coloca isso?

node_modules / react-native / react.gradle.

Coloque isso após o bloco doFirst ()

@AbhishekNairOfficial onde você coloca isso?

node_modules / react-native / react.gradle.

Coloque isso após o bloco doFirst ()

Acho que não é a maneira certa de contornar esse problema. Porque esta alteração será substituída no próximo npm install . Mesmo, o CI não vai funcionar

Alguém tentou os comandos abaixo?

cd android
./gradlew clean
cd ..

Funcionou para mim

O que funcionou para mim foi uma combinação de dois comentários:

Estou colando isso aqui para qualquer pessoa que possa precisar.

def flavorPathSegment = ""
android.productFlavors.all { flavor ->
if (targetName.toLowerCase().contains(flavor.name)) {
                    flavorPathSegment = flavor.name
            }
            }

            doLast {
                def moveFunc = { resSuffix ->
                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}")
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
                        ant.move(file: originalDir, tofile: destDir)
                    }
                }
                def moveRawFunc = { dir ->
                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/${dir}")
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/${dir}")
                        ant.move(file: originalDir, tofile: destDir)
                    }
                }

                moveFunc.curry("ldpi").call()
                moveFunc.curry("mdpi").call()
                moveFunc.curry("hdpi").call()
                moveFunc.curry("xhdpi").call()
                moveFunc.curry("xxhdpi").call()
                moveFunc.curry("xxxhdpi").call()
                moveRawFunc.curry("raw").call()
            }

oh cara, você salvou meu dia <3

O que funcionou para mim foi uma combinação de dois comentários:
Estou colando isso aqui para qualquer pessoa que possa precisar.

def flavorPathSegment = ""
android.productFlavors.all { flavor ->
if (targetName.toLowerCase().contains(flavor.name)) {
                    flavorPathSegment = flavor.name
            }
            }

            doLast {
                def moveFunc = { resSuffix ->
                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}")
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
                        ant.move(file: originalDir, tofile: destDir)
                    }
                }
                def moveRawFunc = { dir ->
                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/${dir}")
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/${dir}")
                        ant.move(file: originalDir, tofile: destDir)
                    }
                }

                moveFunc.curry("ldpi").call()
                moveFunc.curry("mdpi").call()
                moveFunc.curry("hdpi").call()
                moveFunc.curry("xhdpi").call()
                moveFunc.curry("xxhdpi").call()
                moveFunc.curry("xxxhdpi").call()
                moveRawFunc.curry("raw").call()
            }

oh cara, você salvou meu dia <3

Haha, obrigado. Continuei acessando esse tópico quase diariamente, então decidi tornar a vida mais fácil para os outros também.

Remover android/app/build pasta e compilar novamente funcionou para mim.

Minha solução:
Exclua todos os arquivos em / your_project / android / app / src / main / raw / res .
É um trabalho para mim!

O que funcionou para mim foi uma combinação de dois comentários:

Estou colando isso aqui para qualquer pessoa que possa precisar.

def flavorPathSegment = ""
android.productFlavors.all { flavor ->
if (targetName.toLowerCase().contains(flavor.name)) {
                    flavorPathSegment = flavor.name
            }
            }

            doLast {
                def moveFunc = { resSuffix ->
                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}")
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
                        ant.move(file: originalDir, tofile: destDir)
                    }
                }
                def moveRawFunc = { dir ->
                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/${dir}")
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/${dir}")
                        ant.move(file: originalDir, tofile: destDir)
                    }
                }

                moveFunc.curry("ldpi").call()
                moveFunc.curry("mdpi").call()
                moveFunc.curry("hdpi").call()
                moveFunc.curry("xhdpi").call()
                moveFunc.curry("xxhdpi").call()
                moveFunc.curry("xxxhdpi").call()
                moveRawFunc.curry("raw").call()
            }

obrigado @AbhishekNairOfficial. isso economizou muito tempo para mim.

rm -rf ./android/app/src/main/res/drawable-*
rm -rf ./android/app/src/main/res/raw

Então, isso funciona, mas suas imagens estão faltando, então se você recompactar seu aplicativo, tente compilá-lo, obterá o mesmo erro. Alguém já tem uma solução legítima para isso?

Fazer o mesmo na v0.61.5 e como @ wincod75 está dizendo, excluir as pastas raw e drawable não é realmente uma solução, pois todas as imagens são removidas.

Eu entendo que eles são recriados para a versão de lançamento, mas seria bom se eles também funcionassem ao executar o react-native run-android --variant = release, que só funciona quando eles estão em src / main ele se junta e então não é possível construir .

Alguém conseguiu resolver na v0.61.5?

@ gudbrand3 Eu finalmente implementei a correção observada acima para o arquivo "node_modules / react-native / react.gradle," apenas para que eu pudesse obter uma nova compilação para o appstore, mas isso é absurdo de se fazer, não tenho certeza por que isso não aconteceu ainda não foi corrigido ...

@ wincod75 ouça, ouça! Acabei com o mesmo .. blá. Eu também não entendo porque ele não está incluído no pacote até que uma abordagem melhor seja encontrada, já que as pessoas acabam fazendo isso manualmente. Agora, deve ser refeito para cada exclusão de node_modules e reinstalação por minuto. #frustrating

Remover as pastas drawable não funcionaria para mim, pois eu tinha recursos drawable que precisava manter. Meu problema era com duplicate resources para tudo na pasta android/app/src/main/res/raw e arquivos que começavam com nodemodules... na pasta android/app/src/main/res/drawable . Isso resolveu o problema para mim:

Adicionando a android/app/build.gradle :

...
project.ext.react = [
    ...
    bundleInRelease        : true,
    resourcesDirRelease   : "src/release/res",
    ...
]
...

Removendo tudo que começou com node de android/app/src/main/drawable* :

rm android/app/src/main/drawable*/node*
rm -rf android/app/src/main/raw

Limpe o projeto, NÃO EXECUTE O COMANDO DE PACOTES NATIVO REACT e , em seguida, reconstrua

Espero que isso ajude alguém!

Oh garoto. Talvez uma solução oficial esteja a caminho?

Estou tendo o mesmo problema na v.0.61.4

No meu caso
primeiro: coloquei o seguinte código em node_modules / react-native / react.gradle após 'doFirst'

doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
            ant.move(file: originalDir, tofile: destDir);
        }
    }
    moveFunc.curry("ldpi").call()
    moveFunc.curry("mdpi").call()
    moveFunc.curry("hdpi").call()
    moveFunc.curry("xhdpi").call()
    moveFunc.curry("xxhdpi").call()
    moveFunc.curry("xxxhdpi").call()
}

segundo: eu excluí todo o conteúdo da pasta android / app / src / main / res / raw
pode ser útil para alguém

Oh garoto. Talvez uma solução oficial esteja a caminho?

Espero que sim, estou usando RN 0.62.1 e também encontrei esse problema.

Adicionar o código doLast ou excluir as pastas drawables resolve esse problema.

Gostaria de saber qual é a recomendação oficial?

Obrigado

Remover as pastas drawable não funcionaria para mim, pois eu tinha recursos drawable que precisava manter. Meu problema era com duplicate resources para tudo na pasta android/app/src/main/res/raw e arquivos que começavam com nodemodules... na pasta android/app/src/main/res/drawable . Isso resolveu o problema para mim:

Adicionando a android/app/build.gradle :

...
project.ext.react = [
    ...
    bundleInRelease        : true,
    resourcesDirRelease   : "src/release/res",
    ...
]
...

Removendo tudo que começou com node de android/app/src/main/drawable* :

rm android/app/src/main/drawable*/node*
rm -rf android/app/src/main/raw

Limpe o projeto, NÃO EXECUTE O COMANDO DE PACOTES NATIVO REACT e , em seguida, reconstrua

Espero que isso ajude alguém!

A solução acima me ajudou a encontrar uma resposta decente:

Passo 1:

Adicionando a android/app/build.gradle :

... project.ext.react = [ ... bundleInRelease : true, resourcesDirRelease : "src/release/res", ... ] ...

Passo 2:

Execute o seguinte comando para excluir todos os arquivos node_module.

rm -rf drawable*/node*

Etapa 3:

Execute este comando para construir um APK.

./gradlew assembleRelease

Passo 4:

Fiz o seguinte script para usar em meu package.json

"release-apk": "cd android && yarn remove-duplicate-files  && ./gradlew assembleRelease"

Espero que isto ajude!
E obrigado a todos que contribuíram com suas soluções

Para qualquer pessoa que tenha problemas com recursos brutos não relacionados a imagens; Resolvi renomeando os arquivos com o mesmo nome, mas com extensão diferente.

O meu caso

Eu tinha object.obj e object.mtl arquivos. Mesmo se as extensões forem diferentes, ele gerou erro de recursos duplicados. Porque o Android os seleciona pelo nome do arquivo. Então, renomear object.mtl para object_material.mtl tinha finalmente resolvido para mim.

Pode ser o mesmo caso para recursos de imagem também, tente renomeá-los se você tiver imagens com nomes idênticos.

O que funcionou para mim foi uma combinação de dois comentários:

Estou colando isso aqui para qualquer pessoa que possa precisar.

def flavorPathSegment = ""
android.productFlavors.all { flavor ->
if (targetName.toLowerCase().contains(flavor.name)) {
                    flavorPathSegment = flavor.name
            }
            }

            doLast {
                def moveFunc = { resSuffix ->
                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}")
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
                        ant.move(file: originalDir, tofile: destDir)
                    }
                }
                def moveRawFunc = { dir ->
                    File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/${dir}")
                    if (originalDir.exists()) {
                        File destDir = file("$buildDir/../src/main/res/${dir}")
                        ant.move(file: originalDir, tofile: destDir)
                    }
                }

                moveFunc.curry("ldpi").call()
                moveFunc.curry("mdpi").call()
                moveFunc.curry("hdpi").call()
                moveFunc.curry("xhdpi").call()
                moveFunc.curry("xxhdpi").call()
                moveFunc.curry("xxxhdpi").call()
                moveRawFunc.curry("raw").call()
            }

targetName.toLowerCase().contains(flavor.name.toLowerCase()) trabalha para mim.
meu flavor.name parece xxXX.

Todo esse material dolast foi adicionado nos PRs # 24518 e # 24778 e, em seguida, removido novamente em # 25363. Alguém sabe por que foi removido? Este tem sido um problema de pé LONGO, e eu pensei que eles tinham resolvido.

Não importa, as respostas aqui:
https://github.com/facebook/react-native/issues/22234#issuecomment -504721069
e aqui: https://github.com/facebook/react-native/issues/25325

Caso isso ajude, aqui estão algumas linhas do meu script (para o problema do Android X também):

echo "Fixing java error: package android.support.v4.widget does not exist issue with Android X"

npm install jetifier
npx jetify

echo "Fixing duplicate resources issue"
rm -rf .../android/app/src/main/res/raw

cd .../node_modules/react-native

cat <<EOT >> react_gradle.patch
121a122,137
>             doLast {
>                 def moveFunc = { resSuffix ->
>                     File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
>                     if (originalDir.exists()) {
>                         File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
>                         ant.move(file: originalDir, tofile: destDir);
>                     }
>                 }
>                 moveFunc.curry("ldpi").call()
>                 moveFunc.curry("mdpi").call()
>                 moveFunc.curry("hdpi").call()
>                 moveFunc.curry("xhdpi").call()
>                 moveFunc.curry("xxhdpi").call()
>                 moveFunc.curry("xxxhdpi").call()
>             }
> 
EOT

ls -l react_gradle.patch
patch react.gradle react_gradle.patch

E esta solução me ajudou a criar uma versão de lançamento: https://github.com/facebook/react-native/issues/26245#issuecomment -631382817

as etapas a seguir fizeram isso por mim:

1. gradlew clean
2. npm install
3. gradlew bundleRelease
System:
    OS: macOS 10.15.3
    CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
    Memory: 221.64 MB / 8.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.13.1 - ~/.nvm/versions/node/v12.13.1/bin/node
    Yarn: 1.22.4 - ~/Documents/youpendo-app-bareworkflow/node_modules/.bin/yarn
    npm: 6.12.1 - ~/.nvm/versions/node/v12.13.1/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.9.3 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 28, 29
      Build Tools: 28.0.3, 29.0.2
      System Images: android-28 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 3.6 AI-192.7142.36.36.6392135
    Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_232 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: ^4.8.0 => 4.10.0
    react: 16.11.0 => 16.11.0
    react-native: 0.62.2 => 0.62.2
  npmGlobalPackages:
    *react-native*: Not Found

Estou recebendo o mesmo erro. Qualquer solução ?

alguém pode compartilhar o arquivo de patch para o react nativo 0.62.2

Criei este patch para o React Native 0.63.2. Se você tiver pastas ' drawable- , renomeie-as para 'mipmap-' , você pode alterar a referência para elas em android / app / src / main / AndroidManifest.xml

Execute isso na raiz do projeto para criar o arquivo de patch

cat <<EOT >> react-native-0.63.2-react.gradle.patch 
@@ -147,6 +147,23 @@
                 jsSourceMapsDir.mkdirs()
             }

+            doLast {
+                def moveFunc = { resFolder ->
+                    File originalDir = file("\${buildDir}/generated/res/react/release/\${resFolder}");
+                    if (originalDir.exists()) {
+                        File destDir = file("\${buildDir}/../src/main/res/\${resFolder}");
+                        ant.move(file: originalDir, tofile: destDir);
+                    }
+                }
+                moveFunc.curry("drawable-ldpi").call()
+                moveFunc.curry("drawable-mdpi").call()
+                moveFunc.curry("drawable-hdpi").call()
+                moveFunc.curry("drawable-xhdpi").call()
+                moveFunc.curry("drawable-xxhdpi").call()
+                moveFunc.curry("drawable-xxxhdpi").call()
+                moveFunc.curry("raw").call()
+            }
+
             // Set up inputs and outputs so gradle can cache the result
             inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
             outputs.dir(jsBundleDir)
EOT

em seguida, aplique o patch com

patch node_modules/react-native/react.gradle < react-native-0.63.2-react.gradle.patch

Também recomendo fazer

rm -Rf android/.gradle
cd android && gradlew clean

Copie node_ modules/react-native/react.gradle para android/app/react.gradle , a seguir, modifique android/app/build.gradle e android/app/react.gradle :

android/app/build.gradle

- apply from: "../../node_modules/react-native/react.gradle"
+ apply from: "./react.gradle"

android/app/react.gradle

           doFirst {
                jsBundleDir.deleteDir()
                jsBundleDir.mkdirs()
                resourcesDir.deleteDir()
                resourcesDir.mkdirs()
                jsIntermediateSourceMapsDir.deleteDir()
                jsIntermediateSourceMapsDir.mkdirs()
                jsSourceMapsDir.deleteDir()
                jsSourceMapsDir.mkdirs()
            }
+
+           doLast {
+               def moveFunc = { resSuffix ->
+                   File originalDir = file("${resourcesDir}/drawable-${resSuffix}")
+                   if (originalDir.exists()) {
+                      File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}")
+                       ant.move(file: originalDir, tofile: destDir)
+                   }
+               }
+               def moveRawFunc = { dir ->
+                  File originalDir = file("${resourcesDir}/${dir}")
+                  if (originalDir.exists()) {
+                      File destDir = file("$buildDir/../src/main/res/${dir}")
+                      ant.move(file: originalDir, tofile: destDir)
+                  }
+              }
+
+              moveFunc.curry("ldpi").call()
+              moveFunc.curry("mdpi").call()
+              moveFunc.curry("hdpi").call()
+              moveFunc.curry("xhdpi").call()
+              moveFunc.curry("xxhdpi").call()
+              moveFunc.curry("xxxhdpi").call()
+              moveRawFunc.curry("raw").call()
+          }

Isso funciona para mim em react-native 0.63.2

            doLast {
                def flavorPathSegment = ""
                println targetName.toLowerCase();
                android.productFlavors.all { flavor ->
                    if (targetName.toLowerCase().contains(flavor.name.toLowerCase())) {
                        flavorPathSegment = flavor.name
                    }
                }
                def moveFunc = { resFolder ->
                    File originalDir = file("${buildDir}/generated/res/react/${flavorPathSegment}/release/${resFolder}");
                    if (originalDir.exists()) {
                        File destDir = file("${buildDir}/../src/main/res/${resFolder}");
                        ant.move(file: originalDir, tofile: destDir);
                    }
                }

                moveFunc.curry("drawable").call()
                moveFunc.curry("drawable-ldpi").call()
                moveFunc.curry("drawable-mdpi").call()
                moveFunc.curry("drawable-hdpi").call()
                moveFunc.curry("drawable-xhdpi").call()
                moveFunc.curry("drawable-xxhdpi").call()
                moveFunc.curry("drawable-xxxhdpi").call()
                moveFunc.curry("raw").call()
            }


Aqui, o arquivo de patch react-native+0.63.2.patch

diff --git a/node_modules/react-native/react.gradle b/node_modules/react-native/react.gradle
index 6441d93..1eb4645 100644
--- a/node_modules/react-native/react.gradle
+++ b/node_modules/react-native/react.gradle
@@ -147,6 +147,33 @@ afterEvaluate {
                 jsSourceMapsDir.mkdirs()
             }

+            doLast {
+                def flavorPathSegment = ""
+                println targetName.toLowerCase();
+                android.productFlavors.all { flavor ->
+                    if (targetName.toLowerCase().contains(flavor.name.toLowerCase())) {
+                        flavorPathSegment = flavor.name
+                    }
+                }
+                def moveFunc = { resFolder ->
+                    File originalDir = file("${buildDir}/generated/res/react/${flavorPathSegment}/release/${resFolder}");
+                    if (originalDir.exists()) {
+                        File destDir = file("${buildDir}/../src/main/res/${resFolder}");
+                        ant.move(file: originalDir, tofile: destDir);
+                    }
+                }
+
+                moveFunc.curry("drawable").call()
+                moveFunc.curry("drawable-ldpi").call()
+                moveFunc.curry("drawable-mdpi").call()
+                moveFunc.curry("drawable-hdpi").call()
+                moveFunc.curry("drawable-xhdpi").call()
+                moveFunc.curry("drawable-xxhdpi").call()
+                moveFunc.curry("drawable-xxxhdpi").call()
+                moveFunc.curry("raw").call()
+            }
+
+
             // Set up inputs and outputs so gradle can cache the result
             inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
             outputs.dir(jsBundleDir)
diff --git a/node_modules/react-native/scripts/.packager.env b/node_modules/react-native/scripts/.packager.env
new file mode 100644
index 0000000..21a13cf
--- /dev/null
+++ b/node_modules/react-native/scripts/.packager.env
@@ -0,0 +1 @@
+export RCT_METRO_PORT=8081
\ No newline at end of file

Olá a todos! Alguém poderia fazer um PR para essas mudanças? Editar node_modules não é o ideal.

Olá a todos,

Estou usando o reagente nativo 0.63.2. Eu também enfrentei esse problema e tentei editar react.gradle, recursos deletados / drawable e tudo. Mas, finalmente, executar o comando gradlew assembleRelease funcionou para mim.

Não executei o comando do bundle react-native. gradlew assembleRelease está executando o pacote reagente nativo e construindo o próprio apk.

Isso funciona para mim em react-native 0.63.2

            doLast {
                def flavorPathSegment = ""
                println targetName.toLowerCase();
                android.productFlavors.all { flavor ->
                    if (targetName.toLowerCase().contains(flavor.name.toLowerCase())) {
                        flavorPathSegment = flavor.name
                    }
                }
                def moveFunc = { resFolder ->
                    File originalDir = file("${buildDir}/generated/res/react/${flavorPathSegment}/release/${resFolder}");
                    if (originalDir.exists()) {
                        File destDir = file("${buildDir}/../src/main/res/${resFolder}");
                        ant.move(file: originalDir, tofile: destDir);
                    }
                }

                moveFunc.curry("drawable").call()
                moveFunc.curry("drawable-ldpi").call()
                moveFunc.curry("drawable-mdpi").call()
                moveFunc.curry("drawable-hdpi").call()
                moveFunc.curry("drawable-xhdpi").call()
                moveFunc.curry("drawable-xxhdpi").call()
                moveFunc.curry("drawable-xxxhdpi").call()
                moveFunc.curry("raw").call()
            }

Aqui, o arquivo de patch react-native+0.63.2.patch

diff --git a/node_modules/react-native/react.gradle b/node_modules/react-native/react.gradle
index 6441d93..1eb4645 100644
--- a/node_modules/react-native/react.gradle
+++ b/node_modules/react-native/react.gradle
@@ -147,6 +147,33 @@ afterEvaluate {
                 jsSourceMapsDir.mkdirs()
             }

+            doLast {
+                def flavorPathSegment = ""
+                println targetName.toLowerCase();
+                android.productFlavors.all { flavor ->
+                    if (targetName.toLowerCase().contains(flavor.name.toLowerCase())) {
+                        flavorPathSegment = flavor.name
+                    }
+                }
+                def moveFunc = { resFolder ->
+                    File originalDir = file("${buildDir}/generated/res/react/${flavorPathSegment}/release/${resFolder}");
+                    if (originalDir.exists()) {
+                        File destDir = file("${buildDir}/../src/main/res/${resFolder}");
+                        ant.move(file: originalDir, tofile: destDir);
+                    }
+                }
+
+                moveFunc.curry("drawable").call()
+                moveFunc.curry("drawable-ldpi").call()
+                moveFunc.curry("drawable-mdpi").call()
+                moveFunc.curry("drawable-hdpi").call()
+                moveFunc.curry("drawable-xhdpi").call()
+                moveFunc.curry("drawable-xxhdpi").call()
+                moveFunc.curry("drawable-xxxhdpi").call()
+                moveFunc.curry("raw").call()
+            }
+
+
             // Set up inputs and outputs so gradle can cache the result
             inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
             outputs.dir(jsBundleDir)
diff --git a/node_modules/react-native/scripts/.packager.env b/node_modules/react-native/scripts/.packager.env
new file mode 100644
index 0000000..21a13cf
--- /dev/null
+++ b/node_modules/react-native/scripts/.packager.env
@@ -0,0 +1 @@
+export RCT_METRO_PORT=8081
\ No newline at end of file

obrigado

Esta página foi útil?
0 / 5 - 0 avaliações