React-native: [Android] Ошибка: повторяющиеся ресурсы

Созданный на 10 нояб. 2018  ·  103Комментарии  ·  Источник: facebook/react-native

Окружающая обстановка

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

Описание

Я не могу создать релиз apk с изображением PNG в Android. Но может создать релиз apk, когда в нем нет изображения PNG. Вот ошибка, которую я получаю при создании сборки выпуска

[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

Воспроизводимая демонстрация

  1. Создать приложение - react-native init demo
  2. Создайте папку assets в корневой папке проекта.
  3. Добавьте изображение PNG в папку с ресурсами.
  4. Теперь реализуйте компонент image с вышеуказанным изображением PNG.
  5. Теперь свяжите его с помощью 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. Затем сгенерируйте релиз apk с помощью Generate Signed APK
Bug Android

Самый полезный комментарий

Ответ Mapsy должен помочь https://stackoverflow.com/a/52750886
Итак, в основном вы редактируете файл /node_modules/react-native/react.gradle
и вручную добавьте doLast сразу после блока doFirst .

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()
}

Все 103 Комментарий

проверьте это https://github.com/facebook/react-native/issues/19239#issuecomment -414564404

Вам нужно удалить изображение папки с возможностью переноса, если оно есть?

@ ZeroCool00 не повлияет ли это на изображения в Android?

Ответ Mapsy должен помочь https://stackoverflow.com/a/52750886
Итак, в основном вы редактируете файл /node_modules/react-native/react.gradle
и вручную добавьте doLast сразу после блока doFirst .

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 Я проверил оба ваших ответа, он работает. Спасибо, ребята :)

Привет всем, как мы сможем это сделать с помощью Дженкинса. Поскольку он всегда будет выполнять установку npm, которая отменяет это изменение в файле response.gradle. Мы можем создать сборку на android studio для android, но это невозможно на jenkins.

Привет @ vivek-walecha-657 Я не пробовал это, но вы можете попробовать эту команду для создания автономного бандлинга

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

@jeffreyrajanofficial Спасибо за письмо, предоставленное вами решение поможет, если мы изменим файл response.gradle. Но я не хочу делать релиз, меняя файл response.gradle каждый раз, когда я везде устанавливаю npm.

@jeffreyrajanofficial Не могли бы вы сказать, какая версия (последняя ниже этой или выше этой) работает нормально, без этой проблемы. Поскольку в примечаниях к выпуску ничего не говорится о том, что эта проблема решена.

Теперь все отсортировано в RN> 57. Файл response.gradle автоматически создает пакет.
для создания сборки выпуска вам не нужно запускать сборку npm run

Использование нативной версии 55.4, вот мой пример проекта для build.gradle package.json с исправлениями.

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

Я все еще видел это, используя macOS 10.14.3 + RN 0.57.8 + Android Studio 3.3 + Gradle 4.10.3. Может я не один такой? Или, может быть, кто-то здесь может подтвердить, что это работает, поэтому я покопаюсь и исправлю это для себя по-настоящему.

В настоящее время я работаю над этим с пакетом «patch-package» в сочетании с прикрепленным патчем на основе приведенного выше комментария от @mkchx (с добавленным суффиксом .txt чтобы github принял вложение), чтобы автоматически исправить это при 'npm install' после добавления postinstall: patch-package в мои скрипты package.json.

Может это кому пригодится ...
реагировать-родной + 0.57.8.patch.txt

Удалите файлы, которые могут быть у вас:

Android / приложение / SRC / основной / res / вытяжка-mdpi /
Android / приложение / SRC / основной / res / вытяжка-xhdpi /
Android / приложение / SRC / основной / res / вытяжка-xxhdpi /
Запустите сборку снова, это устранило проблему для меня.

Я все еще видел это в RN0.58.x, и это продолжается в RN0.59.x - мы здесь что-то делаем не так или это действительно ошибка?

Я по-прежнему успешно использую обходной путь от @mkchx, закодированный в форме патча в каталоге патчей, для использования с модулем пакета патчей и этим патчем (обновленным для RN0.59.1)

реагировать-родной + 0.59.1.patch.txt

Если у вас есть дополнительные ресурсы, добавленные в пользовательские папки, вы можете попробовать что-то вроде этого:

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()
}

Но если у вас есть зависимости, которые упаковывают свои собственные активы, это не работает, по-прежнему появляется эта ошибка (отредактировано для ясности):

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

Это активно оценивается, или мы должны двигаться дальше с нашими собственными исправлениями?

@dragosroua Я вижу пропущенный дефис в вашем карри xxxhdpi. Случайно такие же ведущие пути с проблемами для вас?

Вы опередили меня на 2 минуты, я собирался редактировать эту часть. Да, сейчас все в комплекте, но бит с «сырым» путем для пользовательских ресурсов может кому-то пригодиться.

@dragosroua рад, что вы сейчас компилируете - я помню, как это меня расстраивало, и я все еще удивлен, что он не исправлен в мастере, хотя я тоже не предлагал PR, так что, думаю, я получил то, что вложил. ..

Я все еще видел это, используя macOS 10.14.3 + RN 0.57.8 + Android Studio 3.3 + Gradle 4.10.3. Может я не один такой? Или, может быть, кто-то здесь может подтвердить, что это работает, поэтому я покопаюсь и исправлю это для себя по-настоящему.

В настоящее время я работаю над этим с пакетом «patch-package» в сочетании с прикрепленным патчем на основе приведенного выше комментария от @mkchx (с добавленным суффиксом .txt чтобы github принял вложение), чтобы автоматически исправить это при 'npm install' после добавления postinstall: patch-package в мои скрипты package.json.

Может это кому пригодится ...
реагировать-родной + 0.57.8.patch.txt

Пожалуйста, объясните мне, почему для моей версии 0.57.5 это не работает?
Я создал файл pacth. Добавлен в package.json. Запустите npm install и в результате

        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

без необходимых изменений.

@zakabluk вам нужно будет опубликовать вывод вашей установки npm, но, как предполагается, это связано с тем, что пакет patch-package очень осторожен с номерами версий. вы пытаетесь на 57.5, а патч против 57.8?

Я обычно делаю скрипты на Python для исправления node_modules.
Добавьте это как postinstall.py и добавьте его в свой скрипт после установки или запустите его с помощью ./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()

Здесь вы можете добавить свои собственные скрипты при необходимости

Похоже на повторную реализацию того, что вы получаете с npm install patch-package но если вам нравится python и вы хотите поддерживать больше кода самостоятельно, это кажется жизнеспособным. Я до сих пор использую патч-пакет для чего он стоит, с 0.59.3 вроде так
реагировать-родной + 0.59.3.patch.txt

@hramos - # 19239 был похож (я думаю), и это давно, но, похоже, есть исправление. Нужен ли просто PR для окончательного исправления, или я упускаю причину, по которой используемый здесь патч нежизнеспособен? (Я могу быть). Если нам просто нужен PR, я могу отправить его ...

Похоже на повторную реализацию того, что вы получаете с npm install patch-package но если вам нравится python и вы хотите поддерживать больше кода самостоятельно, это кажется жизнеспособным. Я до сих пор использую патч-пакет для чего он стоит, с 0.59.3 вроде так
реагировать-родной + 0.59.3.patch.txt

@hramos - # 19239 был похож (я думаю), и это давно, но, похоже, есть исправление. Нужен ли просто PR для окончательного исправления, или я упускаю причину, по которой используемый здесь патч нежизнеспособен? (Я могу быть). Если нам просто нужен PR, я могу отправить его ...

Как использовать этот путь, спасибо

@ZhanRu - https://github.com/ds300/patch-package#set -up - вы просто хотите поместить этот патч (с расширением .patch) в каталог 'patches' вашего проекта после установки и настройки patch- пакет

@ZhanRu - https://github.com/ds300/patch-package#set -up - вы просто хотите поместить этот патч (с расширением .patch) в каталог 'patches' вашего проекта после установки и настройки patch- пакет

большое спасибо

Для тех, кто все еще следит за мной, я недавно интегрировал внешнюю систему и мне нужно было отделить свое тестирование от производственных внешних данных, что привело к использованию «ароматов» в gradle, чтобы вы могли иметь qaDebug, stagingRelease и т.д., указывающие на другую внешнюю систему. Патч здесь не поддерживал это, поэтому я добавил поддержку разновидностей, и теперь мой патч выглядит так. Он находится в patches/react-native+0.59.5.patch где он применяется во время npm i запускается после 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)

В моем случае проблема сохраняется с каталогом raw .

Версия: react-native 0.59.5

Мое решение:

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()
}

С уважением

@Dbroqua у меня react-native 0.59.5 ). Спасибо.

Очень интересно - у меня не было проблем с raw - имейте в виду, что моя последняя версия патча добавила поддержку ароматов. Если вы начнете создавать ароматы, вам понадобится поддержка ароматов в обеих этих функциях. Возможно, это можно было бы как-то параметризовать, чтобы две функции не повторялись, но я недостаточно хорош в Groovy, чтобы рассматривать это.

Я могу только представить, что это не проблема facebook и CI, поддерживающих реакцию, потому что они каждый раз используют BUCK и их сборки CI чистые. Есть ли у кого-нибудь чистая копия этого, чтобы мы могли исправить это в апстриме?

В моем случае необработанный каталог содержит некоторые mp3, используемые в моем приложении.

Тогда это может стать основой для быстрого и легкого воспроизведения. У меня нет таких активов (пока), но достаточно легко, чтобы реагировать на собственный init для репо, помещать некоторые активы, а затем, я думаю, во второй сборке выпуска (может быть, даже в первой?) Вы попали ...

@Dbroqua просто

В порядке,

Я сделаю необходимое как можно скорее.

С Уважением,
Дэмиен

Исправлена!

В моем случае в каталогах drawables res/drawable-* были файлы, которые оставались от какого-то другого разработчика в моей команде - я получал сообщение «Ошибка: повторяющиеся ресурсы», указывающее на эти имена файлов - я удалил файлы из чертежей и все отлично работает 👍

Ответ Mapsy должен помочь https://stackoverflow.com/a/52750886
Итак, в основном вы редактируете файл /node_modules/react-native/react.gradle
и вручную добавьте doLast сразу после блока doFirst .

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()
}

у меня не работает.

@ Nextt1 вам нужно будет открыть новый выпуск - с воспроизводимым тестовым примером в публичном репо, если это вообще возможно - и, возможно, предложить новый PR. Эта проблема была закрыта моим PR, а затем была объединена еще одна (обработка случая, когда мой первый PR не прошел должным образом), поэтому мы все двинулись дальше, и я думаю, что для большинства он работает, поэтому эта проблема вряд ли возникнет. внимание.

Привет всем - PR, который я предложил исправить это, был объединен, но, очевидно, вызывает регресс - https://github.com/facebook/react-native/issues/25325 - Я изучаю, но есть ли здесь какие-либо гуру Gradle, которые сейчас как исправить эту проблему, не вызывая этого регресса, помощь будет оценена - спасибо!

Хорошо, связанный PR здесь будет иметь «обратный PR» - он вызывает регресс, и основная проблема, которая вызвала эту проблему, была действительно плохой документацией.

Вот в чем дело: вы никогда не должны копировать что-либо в каталог src во время сборки. Вам нужно скопировать вещи в промежуточные и сгенерированные и т. Д. Если вы уже скопировали вещи в src (из предыдущих сборок с использованием этого патча или из команды пакета response-native): вам нужно очистить их, чтобы ваш src / main / res каталог чистый - только реальные активы из вашего проекта

Теперь, чтобы создать APK с автономным пакетом - даже в dev, чтобы вы могли запускать его на API <17, вы должны делать что-то не так, как рекомендует каждый в Интернете (или у вас возникнет эта проблема).

Вы хотите, чтобы в вашем 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
]

Затем вы вызываете react-native примерно так - отправляя свойство проекта gradle через переменную среды:
ORG_GRADLE_PROJECT_bundleInDebug=true npx react-native run-android

(или для вариантов что-то вроде этого ORG_GRADLE_PROJECT_bundleInDevDebug=true npx react-native run-android --variant devDebug )

Я все еще видел это, используя macOS 10.14.3 + RN 0.57.8 + Android Studio 3.3 + Gradle 4.10.3. Может я не один такой? Или, может быть, кто-то здесь может подтвердить, что это работает, поэтому я покопаюсь и исправлю это для себя по-настоящему.

В настоящее время я работаю над этим с пакетом «patch-package» в сочетании с прикрепленным патчем на основе приведенного выше комментария от @mkchx (с добавленным суффиксом .txt чтобы github принял вложение), чтобы автоматически исправить это при 'npm install' после добавления postinstall: patch-package в мои скрипты package.json.

Может это кому пригодится ...
реагировать-родной + 0.57.8.patch.txt

Потрясающе! На данный момент это лучший ответ!

Я все еще вижу это в 0.59.9. Ответ @mkchx помог мне решить проблему

@juliancorrea @scgough, будьте осторожны с этим, я следовал этому стилю решения до конца, даже с принятым PR, но после последующих проблем нам нужно было отменить его. Это тупиковое решение. Я опубликовал полную информацию о рекомендуемом в настоящее время решении в нескольких комментариях выше и могу рекомендовать только новый стиль. Если вы используете мой старый прикрепленный патч на основе ответа

@mikehardy Хорошо, сейчас я посмотрю на ваше решение.
Я _ думаю_, что я действительно хочу, чтобы подписанная сборка APK Android Studio пропустила пакет (поскольку я делаю это вручную через терминал).
Я посмотрю на предоставленные вами настройки и посмотрю, помогут ли они.

У меня все еще проблемы с этим ...
Кажется, я не могу создать свой APK-файл релиза. Я получаю следующую ошибку для каждого файла активов:

[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 : Ошибка: повторяющиеся ресурсы

Я удалил оба экземпляра папок drawable-mdpi но генерация APK помещает их обратно и ошибки.
Я запускаю следующее вручную, чтобы создать свой пакет:

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/

В моем приложении Gradle у меня есть:

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

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

Так же, как дополнительная информация - мое приложение отлично работает при отладке (через react-native run-android )
На данный момент единственный способ собрать свой APK-файл - это исправить исправление PR doLast указанное выше.

Я думаю, что, по крайней мере, у меня есть причина / решение моей проблемы.

Моя старая команда bundle (я использовал с RN 0.2.x ?!) отправила ресурсы в папку назначения android/app/src/main/res/

Я заметил сообщение по приведенной ниже ссылке, в котором говорится, что> RN 57 действительно требует, чтобы активы были помещены в следующую папку:
android/app/build/intermediates/res/merged/release/

Источник: https://github.com/facebook/react-native/issues/19211#issuecomment -448301870

Я сделал следующее:

  • удалил drawable-mdpi активы, которые были скопированы в android/app/src/main/res/
  • обновил команду моего пакета, чтобы использовать новое расположение папки
  • теперь мой APK собирается ... (_ Я собираюсь его протестировать_)

Обновить
APK установлен, но приложение теперь вылетает за исключением:
com.facebook.react.bridge.JSApplicationIllegalArgumentException: Error while updating property 'defaultSrc' of a view managed by: RCTImageView

... так что, похоже, он не может найти изображения 😞

обновление 2
Единственный способ заставить APK работать (пока) - это сделать следующее:

  • откатить мой вызов пакета, чтобы использовать следующее для активов: android/app/src/main/res/
  • запустите команду bundle
  • переименуйте android/app/src/main/res/drawable-mdpi в android/app/src/main/res/drawable-hdpi
  • создать подписанный APK

мой градиент сборки:

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

Затем APK собирается и запускается ...

Примечание:
У меня возникла неожиданная ошибка, которая привела к исключению createBitmap OutOfMemory в компоненте слайдера изображения.
Я добавил в свой манифест следующее, и приложение снова запускается: android:largeHeap="true"
Я знаю, что добавление позволяет обойти проблему, которая может быть утечкой / компонентом, но пока приложение снова работает без проблем.

В React Native 0.60.0 я заметил, что собственная база также создает дублирующиеся ресурсы, но описанный выше обходной путь не сработает, потому что он нацелен на необработанную папку.

[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: Ошибка: повторяющиеся ресурсы

Для других пользователей, у которых возникла эта проблема:

        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);
            }
        }

как мы можем решить эту проблему, если мы используем CI?

В моем случае проблема сохраняется с каталогом raw .

Версия: react-native 0.59.5

Мое решение:

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()
}

С уважением

Это работает!

[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

Я получаю эту ошибку при запуске react-native run-android но не при сборке и запуске сборки выпуска. Ни одно из вышеперечисленных решений у меня не работает.

РН 0.60.5

ОБНОВЛЕНИЕ: я понял, что должен изменить вышеуказанные методы «патча», чтобы указать каталоги debug вместо release и это исправило это. Мне тоже пришлось исправить мой каталог raw

У меня тоже такая же проблема, и патч response.gradle не исправит ее. В моем случае мои дублированные ресурсы - это файлы .OBJ и .MTL, проблем с ресурсами изображений нет.

[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_saladApp] / Users / sercanov / Projects / Diner /android/app/src/main/res/raw/assets_res_salad_salad.obj: ошибка: повторяющиеся ресурсы
[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 / Diner /android/app/src/main/res/raw/assets_res_steak_steak.obj: ошибка: повторяющиеся ресурсы
[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_salmonApp] / Users / sercanov / Projects / Diner /android/app/src/main/res/raw/assets_res_salmon_salmon.obj: ошибка: повторяющиеся ресурсы

@sercanov вы все еще пытаетесь использовать копию для src? Этот стиль был исследован и не работает по известным причинам; существуют поддерживаемые способы сборки, которые не помещают вещи в src - или вы пытаетесь использовать способы без копирования в src и все еще терпите неудачу? https://github.com/facebook/react-native/issues/22234#issuecomment -504721069

эй, @mikehardy на самом деле пробовал оба подхода, ни один из них не работал в сборках релизов. Кстати, в режиме отладки он работает нормально.

При использовании способа not-copy-to-src ORG_GRADLE_PROJECT_bundleInArRelease=true npx react-native run-android --variant arRelease я получаю это;

Ошибка выполнения для задачи ': 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_saladov] / Users_saladov] / /ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_salad_salad.obj: ошибка: повторяющиеся ресурсы
[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_steakov] / Users / sercan_steakov] / /ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_steak_steak.obj: ошибка: повторяющиеся ресурсы
[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_sal Pro / Sermon_salmonov] / Users / sercan /ARt/diner/DinerApp/android/app/build/generated/res/react/ar/release/raw/assets_res_salmon_salmon.obj: ошибка: повторяющиеся ресурсы

При использовании copy-to-src doLast way; Мне приходилось очищать папку android / build каждый раз, когда я строю, чтобы добиться успеха, но почему-то активы не были доступны в приложении. Это может быть связано с моим кодом, который сейчас расследуется.

При переключении на способ not-copy-to-src вы должны сначала очистить все, чтобы переключиться. В моем проекте было много "мусора" с точки зрения объединения из предыдущего стиля copy-to-src, который мне приходилось убирать, прежде чем он заработал, а затем он работал каждый раз.

@ rahulkumar1409 это помогло мне в этой ошибке, но выдает другую ошибку

Задача: реагировать-родной-простой- менеджер загрузок

Вы хоть представляете, почему это произошло ??

Это решение сработало для меня.
Итак, в основном вы редактируете файл /node_modules/react-native/react.gradle
и вручную добавьте doLast сразу после блока doFirst.

doFirst {...}
doLast {
def moveFunc = {resSuffix ->
Файл originalDir = file ("$ buildDir / created / res / react / release / drawable - $ {resSuffix}");
if (originalDir.exists ()) {
Файл destDir = file ("$ buildDir /../ src / main / res / drawable - $ {resSuffix}");
ant.move (файл: 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 ()
}

Мы используем react-native 0.60.5.

Мы используем разновидности продуктов, подобные упомянутому @mikehardy, и у нас были проблемы с «сырой» папкой, как и у @Dbroqua .

В итоге я смешал оба решения, и мы используем этот код:

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()
}

Эта ветка была действительно полезной, спасибо всем за участие. 😄

Я получаю повторяющуюся ошибку только в сборках релизов. Я использую react-native 60.5

/release/drawable-xhdpi/node_modules_reactnavigationstack_lib_module_views_assets_backicon.png: ошибка: повторяющиеся ресурсы

Я пробовал установить для bundleInDebug значение true и false, но безрезультатно.

Я использую центр приложений, для этого требуется файл src / main / assets / appcenter-config.json. У меня также есть каталог src / main / assets / fonts, так как я использую собственные шрифты. Может ли это быть причиной проблемы?

@ARichIVC Я предполагаю, что проблема в файле, указанном в вашем сообщении об ошибке.

Похоже, что стандартная проблема «мой каталог src / загрязнена из-за предыдущих попыток обработки пакетов в стиле копирования» из этого исходного решения, прежде чем мы все поняли, что это тупиковое решение, и вам нужно очистить src / из скопированных вещи, прежде чем попробовать следующее решение для выполнения материала bundleInDebug. Все это в этой теме, которая, к сожалению, длинная и громоздкая, но информация там есть

Спасибо @mikehardy за вашу помощь. Я обнаружил, что можно оставить шрифты и т. Д. В каталоге ресурсов, но мне нужно было удалить другие фрагменты, которые остались. А именно все в \ android \ app \ src \ main \ res \ drawable-hdpi \

Обратите внимание, что даже для шрифтов они должны быть в правильном каталоге - пример: https://github.com/oblador/react-native-vector-icons#android, который указывает вам вызвать этот файл, который тщательно копирует в не-src каталог https://github.com/oblador/react-native-vector-icons/blob/master/fonts.gradle#L16 - проект у всех, конечно, разный, но я подумал, что стоит упомянуть

Мы используем react-native 0.60.5.

Мы используем разновидности продуктов, подобные упомянутому @mikehardy, и у нас были проблемы с «сырой» папкой, как и у @Dbroqua .

В итоге я смешал оба решения, и мы используем этот код:

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()
}

Эта ветка была действительно полезной, спасибо всем за участие. 😄

оно работает! Спасибо большое! 👍

Для реакции на native 0.59.1 или выше вам необходимо добавить код ниже в response.gradle в node_modules / react-native.

для ароматизированного использования под кодом.

        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-systematix это плохой совет. Это стилевое решение было реализовано до такой степени, что имело место пиар и даже было слито. Затем было обнаружено, что это неверное направление, и PR был отменен. Вы бы посоветовали людям использовать решение, которое фактически привело к отмене слияния PR? Я не стал бы. https://github.com/facebook/react-native/issues/22234#issuecomment -504721069

@mikehardy Да, я знаю, что это не постоянное решение, но оно работает нормально. А также я не могу использовать ваше решение, потому что у меня есть некоторые другие файлы, такие как заставки и БД, в каталоге res .

Да @ dayachand-systematix я тоже:

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

И все же предлагаемое / не возвращаемое PR решение для меня работает: man_shrugging:

Привет, мы исправили это, удалив параметр --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 привет - удаление параметра --asset-dest приведет к тому, что последние активы не будут объединены в правильное место ... поэтому при создании APK существует опасность того, что дата файлов ресурсов в приложении?

@scgough Я подумал, что это может быть так. Если это так, мы можем выборочно удалить все повторяющиеся активы, за исключением локальных активов, которые нам нужны перед сборкой с помощью Android Studio или любого другого производственного рабочего процесса, например

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

Не идеально, но он должен работать, пока проблема не будет решена.

Эта проблема возникает, когда у вас есть файлы с одинаковым именем и другим расширением в такой папке с ресурсами.

back.png
back.jpg

потому что в android они оба так звонят;

R.drawable.back
R.drawable.back

удалить или переименовать один из файлов.

Привет,
Я попытался изменить response.gradle: сборка идет еще дальше (app.aab уже собран, но я не могу собрать APK.

Я пытался собрать APK с помощью Android Studio, и проблем не было (с патчем для react.gradle).
Для меня это довольно странно, потому что процесс создания APK в обоих случаях должен быть одинаковым. Я ошибся ?

Этот комментарий работал на 0.59.10. Смешанный с этой сущностью .

Большое спасибо, @ dayachand-systematix!

Для меня сработало сочетание двух комментариев:

Я вставляю это здесь для всех, кому это может понадобиться.

``
def FlavourPathSegment = ""
android.productFlavors.all {аромат ->
if (targetName.toLowerCase (). contains (flame.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, где вы это положили?

@AbhishekNairOfficial, где вы это положили?

node_modules / response-native / response.gradle.

Поместите это после блока doFirst ()

@AbhishekNairOfficial, где вы это положили?

node_modules / response-native / response.gradle.

Поместите это после блока doFirst ()

Я думаю, это неправильный способ решения этой проблемы. Потому что это изменение будет отменено при следующем npm install . Даже CI не будет работать

Кто-то пробовал команды ниже?

cd android
./gradlew clean
cd ..

Это сработало для меня

Для меня сработало сочетание двух комментариев:

Я вставляю это здесь для всех, кому это может понадобиться.

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()
            }

о, ты спас мне день <3

Для меня сработало сочетание двух комментариев:
Я вставляю это здесь для всех, кому это может понадобиться.

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()
            }

о, ты спас мне день <3

Хаха спасибо. Я заходил в эту ветку почти ежедневно, поэтому решил облегчить жизнь и другим.

Удаление папки android/app/build и создание снова сработало для меня.

Мое решение:
Удалите все файлы в / your_project / android / app / src / main / raw / res .
Это работа для меня!

Для меня сработало сочетание двух комментариев:

Я вставляю это здесь для всех, кому это может понадобиться.

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()
            }

спасибо @AbhishekNairOfficial. это сэкономило мне много времени.

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

Итак, это работает, но тогда ваши изображения отсутствуют, поэтому, если вы повторно объедините свое приложение, а затем попытаетесь его собрать, вы получите ту же ошибку. У кого-нибудь еще есть законное исправление для этого?

То же самое в v0.61.5 и, как говорит @ wincod75 , удаление необработанных и

Я получаю, что они воссоздаются для сборки выпуска, но было бы неплохо, если бы они также работали при запуске response-native run-android --variant = release, который работает только тогда, когда они находятся в src / main it швы, а затем нельзя построить .

Кто нибудь смог решить на v0.61.5?

@ gudbrand3 В конце концов я реализовал исправление, упомянутое выше, в файле «node_modules / response-native / react.gradle», чтобы я мог получить новую сборку в магазине приложений, но это абсурдно, не знаю, почему это еще не исправлено ...

@ wincod75 слышать слышать! У меня получилось то же самое .. мля. Я также не понимаю, почему он просто не включен в пакет, пока не будет найден лучший подход, поскольку люди все равно делают это вручную. Теперь это нужно делать заново для каждого удаления node_modules и повторной установки npm. # разочарование

Удаление папок с возможностью рисования не сработало для меня, поскольку у меня были ресурсы с возможностью рисования, которые мне нужно было сохранить. Моя проблема заключалась в том, что duplicate resources для всего в папке android/app/src/main/res/raw и файлов, которые начинались с nodemodules... в папке android/app/src/main/res/drawable . Это решило проблему для меня:

Добавление в android/app/build.gradle :

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

Удаление всего, что начинается с node из android/app/src/main/drawable* :

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

Очистите проект, НЕ ВЫПОЛНЯЙТЕ КОМАНДУ REACT NATIVE BUNDLE , а затем выполните сборку заново.

Надеюсь, это кому-то поможет!

О, парень. Может быть официальное исправление уже в пути?

У меня такая же проблема с версией 0.61.4

в моем случае
сначала: я поместил следующий код в node_modules / response-native / react.gradle после 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()
}

второй: удалил все содержимое папки android / app / src / main / res / raw
может быть полезно кому-то

О, парень. Может быть официальное исправление уже в пути?

Надеюсь, я использую RN 0.62.1 и

Эту проблему решает добавление кода doLast или удаление папок с чертежами.

Мне интересно узнать, какая официальная рекомендация?

Спасибо

Удаление папок с возможностью рисования не сработало для меня, поскольку у меня были ресурсы с возможностью рисования, которые мне нужно было сохранить. Моя проблема заключалась в том, что duplicate resources для всего в папке android/app/src/main/res/raw и файлов, которые начинались с nodemodules... в папке android/app/src/main/res/drawable . Это решило проблему для меня:

Добавление в android/app/build.gradle :

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

Удаление всего, что начинается с node из android/app/src/main/drawable* :

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

Очистите проект, НЕ ВЫПОЛНЯЙТЕ КОМАНДУ REACT NATIVE BUNDLE , а затем выполните сборку заново.

Надеюсь, это кому-то поможет!

Приведенное выше решение помогло мне найти достойный ответ:

Шаг 1:

Добавление в android/app/build.gradle :

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

Шаг 2:

Выполните следующую команду, чтобы удалить все файлы node_module.

rm -rf drawable*/node*

Шаг 3:

Выполните эту команду, чтобы собрать APK.

./gradlew assembleRelease

Шаг 4:

Я сделал следующий скрипт для использования в моем package.json

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

Надеюсь это поможет!
И спасибо всем, кто поделился своими решениями

Для тех, у кого есть проблема с необработанными ресурсами без изображений; Я решил это, переименовав файлы с тем же именем, но с другим расширением.

Мое дело

У меня были файлы object.obj и object.mtl . Даже если расширения разные, это вызвало ошибку дублирования ресурсов. Потому что андроид подбирает их по имени файла. Итак, переименование object.mtl в object_material.mtl наконец, решило эту проблему для меня.

То же самое может быть и с ресурсами изображений. Попробуйте переименовать их, если у вас есть изображения с одинаковыми именами.

Для меня сработало сочетание двух комментариев:

Я вставляю это здесь для всех, кому это может понадобиться.

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()) у меня работает.
мои flavor.name выглядят как xxXX.

Вся эта долька была добавлена ​​в PR # 24518 и # 24778, а затем снова удалена в # 25363. Кто-нибудь знает, почему его удалили? Это была давняя проблема, и я подумал, что они ее исправили.

Ничего, ответы здесь:
https://github.com/facebook/react-native/issues/22234#issuecomment -504721069
и здесь: https://github.com/facebook/react-native/issues/25325

В случае, если это поможет, вот пара однострочников из моего скрипта (также для проблемы с Android X):

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

И это решение помогло мне создать сборку релиза: https://github.com/facebook/react-native/issues/26245#issuecomment -631382817

следующие шаги сделали это для меня:

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

Я получаю ту же ошибку. Любое решение?

может кто-нибудь, пожалуйста, поделитесь файлом патча для реагирования на родной 0.62.2

Я создал этот патч для React Native 0.63.2. Если у вас есть «» drawable- папки, переименовывать его «mipmap-», вы можете изменить ссылку на него в Android / приложение / SRC / основной / AndroidManifest.xml

Запустите это в корне проекта, чтобы создать файл патча

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

затем примените патч с

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

Также рекомендую сделать

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

Скопируйте node_ modules/react-native/react.gradle в android/app/react.gradle , затем измените android/app/build.gradle и 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()
+          }

Это работает для меня в 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()
            }


Вот файл патча 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

Привет всем! Может ли кто-нибудь сделать пиар этих изменений? Редактирование node_modules не идеально.

Привет всем,

Я использую версию 0.63.2. Я также столкнулся с этой проблемой и попытался отредактировать response.gradle, удалить ресурсы / drawable и все. Но наконец запуск команды gradlew assembleRelease у меня сработал.

Я не запускал команду пакета response-native. gradlew assembleRelease запускает пакет react-native и создает сам apk.

Это работает для меня в 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()
            }

Вот файл патча 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

благодарю вас

Была ли эта страница полезной?
0 / 5 - 0 рейтинги