React-native: [Android]错误:资源重复

创建于 2018-11-10  ·  103评论  ·  资料来源: facebook/react-native

  • [x]查看文档: https :
  • [x]搜索现有问题: https
  • [x]使用最新的React Native版本: https

环境

反应本机环境信息:

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

描述

我无法在Android中使用PNG图片创建发布APK。 但是,如果其中没有PNG图像,则可以创建发行版APK。 这是我在生成发行版本时遇到的错误

[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. 现在,使用上述PNG图片实现image组件。
  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. 然后使用Generate Signed APK生成发布apk
Bug Android

最有用的评论

Mapsy的答案应该有帮助https://stackoverflow.com/a/52750886
因此,基本上,您可以编辑/node_modules/react-native/react.gradle文件
并手动在doFirst块之后添加doLast

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文件
并手动在doFirst块之后添加doLast

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 install,它会覆盖react.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感谢您的写作,如果我们去更改react.gradle文件,您提供的解决方案将有所帮助。 但是我不想每次我在所有地方进行npm安装时都通过更改react.gradle文件来发布。

@jeffreyrajanofficial您能告诉哪个版本(最新版本低于此版本或高于此版本)运行正常,而不会出现此问题。 因为发行说明并没有告诉您该问题已解决。

现在在RN> 57中对事物进行排序。react.gradle文件自动创建捆绑包。
用于创建发布版本,您不需要运行npm run build:android :release

使用55.4 react native版本是我的带有修复的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看到这一点。 也许我不是唯一的一个? 也许这里有人可以确认它是否有效,所以我会进一步挖掘并自己修复。

我目前正在使用“补丁程序包”软件包以及基于@mkchx的上述注释(附加.txt后缀,以便github接受附件)的附加补丁来解决该问题,以便自动进行将postinstall: patch-package到我的package.json脚本后,在“ npm install”上修复它。

也许这对某人有用...
react-native + 0.57.8.patch.txt

删除您可能拥有的文件:

android / app / src / main / res / drawable-mdpi /
android / app / src / main / res / drawable-xhdpi /
android / app / src / main / res / drawable-xxhdpi /
再次运行Build,这为我解决了这个问题。

我仍然在RN0.58.x中看到这种情况,并在RN0.59.x中继续出现-我们在这里做错了吗,或者这真的是一个错误吗?

我继续使用@mkchx的变通方法取得成功,该变通方法是在补丁目录中以补丁格式编码的,用于补丁程序包模块和此补丁程序(已针对RN0.59.1更新)

react-native + 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,但我仍然感到惊讶的是它还没有在master中解决,所以我想我知道我输入了什么。 ..

我仍然使用MacOS 10.14.3 + RN 0.57.8 + Android Studio 3.3 + Gradle 4.10.3看到这一点。 也许我不是唯一的一个? 也许这里有人可以确认它是否有效,所以我会进一步挖掘并自己修复。

我目前正在使用“补丁程序包”软件包以及基于@mkchx的上述注释(附加.txt后缀,以便github接受附件)的附加补丁来解决该问题,以便自动进行将postinstall: patch-package到我的package.json脚本后,在“ npm install”上修复它。

也许这对某人有用...
react-native + 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?

我通常制作用于修补node_modules的python脚本。
将此添加为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
react-native + 0.59.3.patch.txt

@hramos- #19239是类似的(我认为),这已经存在很长时间了,但是似乎已经解决了。 这仅仅是需要PR才能获得最终修复,还是我错过了此处使用的补丁不可行的原因? (我可能是)。 如果我们只需要公关,我可以寄一个...

看起来像npm install patch-package的实现的重新实现,但是如果python是您的事,并且您想自己维护更多代码,则它似乎是可行的。 我仍在使用补丁程序打包它的价值,像这样的0.59.3
react-native + 0.59.3.patch.txt

@hramos- #19239是类似的(我认为),这已经存在很长时间了,但是似乎已经解决了。 这仅仅是需要PR才能获得最终修复,还是我错过了此处使用的补丁不可行的原因? (我可能是)。 如果我们只需要公关,我可以寄一个...

如何使用这条路,谢谢

@ZhanRu - https: //github.com/ds300/patch-package#set -up-您只想在安装和设置补丁-之后将该补丁(带有.patch扩展名)放入项目的'patches'目录中,包

@ZhanRu - https: //github.com/ds300/patch-package#set -up-您只想在安装和设置补丁-之后将该补丁(带有.patch扩展名)放入项目的'patches'目录中,包

非常感谢你

对于仍在继续的人,我最近集成了一个外部系统,需要将测试与生产外部数据分开,这导致在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没问题-请注意,我的最新版本的补丁增加了对口味的支持。 如果您开始制作调味料,则现在希望这两个功能都支持该调味料。 也许可以通过某种方式对它进行参数化,所以这2个func并没有那么重复,但是我不太擅长于使用Groovy进行研究。

我只能想象这在facebook和本机CI中都不是问题,因为他们正在使用BUCK,并且每次生成的CI都是干净的。 是否有人对此有完整的复制,以便我们可以在上游进行修复?

在我的情况下,原始目录包含我的应用程序中使用的某些mp3。

这可能构成快速轻松再现的基础。 我还没有这样的资产(但还没有),但是足够容易地对本地init进行回购,然后再放一些资产,我认为在第二个发行版(也许甚至是第一个发行版)上,您的工作就白白了。

@Dbroqua只是一个提示,我的补丁已合并,但您提到的原始目录关系非常密切,但未包含在我的补丁中也反映在合并中。 现在,我的补丁已经发布,您可能希望查看原始目录需要进行哪些更改,并提出一个带有该修复程序的续订的PR,以针对您的情况进行扩展?

好,

我将尽快进行必要的处理。

问候,
达米安

固定!

以我为例,可绘制对象res/drawable-*目录中的文件与我团队中其他开发人员遗留下来的提交有关-我收到指向这些文件名的“错误:重复资源”-我从可绘制对象中删除了这些文件一切都很好fine

Mapsy的答案应该有帮助https://stackoverflow.com/a/52750886
因此,基本上,您可以编辑/node_modules/react-native/react.gradle文件
并手动在doFirst块之后添加doLast

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,您将需要打开一个新期刊-尽可能在公共

大家好-公关我提出要解决这个问题被合并,但显然会导致回归- https://github.com/facebook/react-native/issues/25325 -我们正在调查,但如果在这里,现在已经有任何gradle这个大师如何解决此问题而不会导致回归,将不胜感激-谢谢!

好的,这里的相关PR将具有“还原PR”-它导致回归,而导致该问题的潜在问题实际上是不良文档。

事情是这样的:真正不要在构建过程中将东西复制到src目录中。 您需要将内容复制到中间体中并生成等。如果您已经将其复制到src中(使用此修补程序从以前的版本中或从react-native bundle命令复制):您需要清除这些内容,以便src / main / res目录是干净的-仅项目中的真实资产

现在,要使用脱机捆绑包构建APK(即使在开发人员中也是如此),以便您可以在<17的API上运行它,就应该做的事情与网络上每个人的建议都不一样(否则就会遇到此问题)。

您想要的是您的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看到这一点。 也许我不是唯一的一个? 也许这里有人可以确认它是否有效,所以我会进一步挖掘并自己修复。

我目前正在使用“补丁程序包”软件包以及基于@mkchx的上述注释(附加.txt后缀,以便github接受附件)的附加补丁来解决该问题,以便自动进行将postinstall: patch-package到我的package.json脚本后,在“ npm install”上修复它。

也许这对某人有用...
react-native + 0.57.8.patch.txt

太棒了! 目前,这是最好的答案!

我仍然在0.59.9中看到这一点。 @mkchx的答案为我解决了问题

@juliancorrea @scgough对此要小心一点,我一直遵循该解决方案风格,甚至接受了PR,但是在出现后续问题之后,我们需要还原它。 这是一个死胡同的解决方案。 我在上面的一些评论中发布了当前推荐解决方案的完整详细信息,并且只能推荐新样式。 如果您使用我的基于@mkchx的旧附加补丁程序,它将暂时对您有效,但仅在特定条件下有效-在将来您的项目可能需要的其他常见情况下,它会失败

@mikehardy好-我现在来看您的解决方案。
我想我真正想要的是Android Studio的签名APK版本跳过包(因为我是通过终端手动执行此操作)。
我将看看您提供的设置,看看它们是否有帮助。

我对此仍然有麻烦...
我似乎无法创建我的发布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的唯一方法是通过上面的doLast还原PR修复程序。

我想至少我有问题的原因/解决方案。

我的旧束命令(自RN 0.2.x开始使用?!)将资产推送到目标文件夹android/app/src/main/res/

我在下面的链接中注意到一则帖子,该帖子指出> RN 57实际上需要将资产推送到以下文件夹:
android/app/build/intermediates/res/merged/release/

来源: https :

我做了以下事情:

  • 删除了已复制到android/app/src/main/res/drawable-mdpi资产
  • 更新了我的包命令以使用新的文件夹位置
  • 我的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

我的构建gradle是:

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 \ resraw \ node_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 \ react \ releaseraw \ node_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时收到此错误,但在生成并运行发行版时却没有。 以上解决方案均不适用于我。

RN 0.60.5

更新:我意识到我应该修改上述“补丁”方法,以引用debug而不是release目录,并对其进行修复。 我也不得不修复raw目录

我也有同样的问题,react.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_salad] / Users / sercanov / Projects / ARt / diner / DinerApp /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 / ARt / diner / DinerApp /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_salmon] / Users / sercanov / Projects / DinerApp / 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 /生成/res/react/ar/release/raw/assets_res_salad_salad.mtl [raw / assets_res_salad_salad] / Users / sercanov / Projects /ARt/diner/DinerApp/android/app/build/generation/res/react/ar/release/raw/assets_res_salad_salad.obj:错误:资源重复
[raw / assets_res_steak_steak] / Users / sercanov / Projects / ARt / diner / DinerApp / android / app / build /生成/res/react/ar/release/raw/assets_res_steak_steak.mtl [raw / assets_res_steak_steak] / Users / sercanov / Projects /ARt/diner/DinerApp/android/app/build/generation/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_salmon_salmon] / Users / sercanov / Project /ARt/diner/DinerApp/android/app/build/generation/res/react/ar/release/raw/assets_res_salmon_salmon.obj:错误:资源重复

当使用copy-to-src doLast方法时; 每次构建时,我都必须清除android / build文件夹才能使其成功,但不知何故资产在应用程序中不可用。 这可能与我正在研究的代码有关。

切换到非复制到src方式时,您必须先清除所有内容,然后进行切换。 从以前的复制到src样式的捆绑角度来看,我的项目有很多“乱七八糟”,在工作之前我必须清除它,然后每次都起作用。

@ rahulkumar1409这可以帮助我解决此错误,但会引发另一个错误

任务:react-native-simple-download- manager:verifyReleaseResources FAILED

你知道为什么会这样吗?

这个解决方案对我有用。
因此,基本上,您可以编辑/node_modules/react-native/react.gradle文件
并手动在doFirst块之后添加doLast。

doFirst {...}
doLast {
def moveFunc = {resSuffix->
文件originalDir = file(“ $ buildDir / Generated / res / react / release / drawable-$ {resSuffix}”);
如果(originalDir.exists()){
文件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()
}

我们的反应本机为0.60.5。

我们正在使用产品风味,就像@mikehardy提到的一样,我们的'raw'文件夹也有问题,就像@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()
}

感谢所有人的贡献,该线程确实很有帮助。 😄

我只在发行版本上得到重复错误。 我正在使用本机60.5

/release/drawable-xhdpi/node_modules_reactnavigationstack_lib_module_views_assets_backicon.png:错误:资源重复

我尝试将bundleInDebug设置为true和false,但没有任何影响。

我正在使用App Center进行构建,这需要src / main / assets / appcenter-config.json文件。 当我使用自定义字体时,我还有一个src / main / assets / fonts目录。 这可能是造成问题的原因吗?

@ARichIVC我猜问题是您的错误消息中引用的文件。

在我们所有人都意识到这是一个死胡同的解决方案,您需要清除已复制的src /之后,该原始解决方案似乎会出现标准的“我的src /目录被以前的复制样式尝试处理捆绑包污染的问题”。在尝试执行bundleInDebug的后续解决方案之前,请先进行以下操作。 不幸的是,这一切都是冗长而笨拙的,但是信息在那里

感谢@mikehardy的帮助。 我发现可以保留Assets目录中的字体等很好,但是确实需要删除其他零散的东西。 即\ android \ app \ src \ main \ res \ drawable-hdpi \中的所有内容

请注意,即使是字体,它们也应位于正确的目录中-例如: https : https://github.com/oblador/react-native-vector-icons/blob/master/fonts.gradle#L16-每个人的项目当然都不同,但我认为值得一提

我们的反应本机为0.60.5。

我们正在使用产品风味,就像@mikehardy提到的一样,我们的'raw'文件夹也有问题,就像@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 0.59.1或更高版本,您需要在node_modules / react-native中的react.gradle中添加以下代码。

用于代码下面的调味。

        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被恢复。 您是否建议人们使用实际上导致PR合并被还原的解决方案? 我不会。 https://github.com/facebook/react-native/issues/22234#issuecomment -504721069

@mikehardy是的,我知道这不是永久性的解决方案,但是效果很好。 而且我也无法使用您的解决方案,因为我还有一些其他文件,例如启动屏幕和res目录中的DB。

是的,也@ 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

删除或重命名文件之一。

你好
我试图修改react.gradle:构建进一步迈进了一步(app.aab已构建,但我无法构建APK。

我尝试使用Android Studio构建APK,但没有问题(使用react.gradle补丁)。
对我来说,这很奇怪,因为在两种情况下,构建APK的过程应该相同。 我错了吗 ?

该评论的值为0.59.10。 混有这个要点

非常感谢@ dayachand-systematix!

对我有用的是两个评论的组合:

我将其粘贴在这里,供其他可能需要的人使用。

```
def flavourPathSegment =“”
android.productFlavors.all {风味->
如果(targetName.toLowerCase()。contains(flavor.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 / react-native / react.gradle。

将其放在doFirst()块之后

@AbhishekNairOfficial这个放在哪里?

node_modules / react-native / react.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中说的一样,删除原始和可绘制的文件夹并不是真正的解决方案,因为所有图像都被删除了。

我知道它们是为发布版本而重新创建的,但是如果它们在运行react-native run-android --variant = release时也可以工作,那将是很好的选择,仅当它们在src / main中时才有效,然后无法构建。

有人能在v0.61.5上解决吗?

@ gudbrand3我最终实现了对“ node_modules / react-native / react.gradle”文件的上述修复,只是为了使我能够在Appstore中获得一个新的构建,但这是荒谬的,必须这样做,不确定为什么要这样做还没有解决...

@ 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",
    ...
]
...

android/app/src/main/drawable*删除所有以node开头的内容:

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

清理项目,不要运行REACT NATIVE BUNDLE COMMAND ,然后重新构建。

希望这对某人有帮助!

好家伙。 也许官方的解决方案正在进行中?

我在0.6.1.4版上遇到了同样的问题

就我而言
首先:我将以下代码放在“ doFirst”之后的node_modules / react-native / react.gradle中

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代码删除drawables文件夹可解决此问题。

我想知道官方的建议是什么?

谢谢

删除可绘制文件夹对我来说不起作用,因为我需要保留可绘制资源。 我的问题是与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",
    ...
]
...

android/app/src/main/drawable*删除所有以node开头的内容:

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

清理项目,不要运行REACT NATIVE BUNDLE COMMAND ,然后重新构建。

希望这对某人有帮助!

上面的解决方案帮助我找到了一个不错的答案:

第1步:

加到android/app/build.gradle

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

第2步:

运行以下命令删除所有node_module文件。

rm -rf drawable*/node*

第三步:

运行此命令以构建和APK。

./gradlew assembleRelease

步骤4:

我在package.json中使用了以下脚本

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

希望这可以帮助!
并感谢所有提出解决方案的人

对于任何非图片原始资源有问题的人; 我通过重命名具有相同名称但不同扩展名的文件来解决此问题

我的情况

我有object.objobject.mtl文件。 即使扩展名不同,也会引发重复资源错误。 因为android通过文件名来选择它们。 因此,将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。

所有这些dolast东西都添加到PR#24518和#24778中,然后在#25363中再次删除。 有谁知道为什么要删除它? 这一直是一个长期存在的问题,我认为他们已经解决了。

没关系,在这里回答:
https://github.com/facebook/react-native/issues/22234#issuecomment -504721069
并在这里: https :

在有帮助的情况下,以下是我脚本中的几行代码(同样适用于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 :

以下步骤为我做到了:

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 / app / src / main / 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.gradleandroid/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。 我也遇到了这个问题,并尝试编辑react.gradle,删除资源/可绘制内容等。 但是最后运行命令gradlew assembleRelease对我有用。

我没有运行react-native bundle命令。 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 等级

相关问题

vikeri picture vikeri  ·  3评论

josev55 picture josev55  ·  3评论

janmonschke picture janmonschke  ·  3评论

aniss picture aniss  ·  3评论

jlongster picture jlongster  ·  3评论