【问题标题】:React Native Duplicate resourcesReact Native 重复资源
【发布时间】:2019-02-27 02:38:22
【问题描述】:

升级到 React Native 0.57 后,我在 react-native-router-flux 中生成 APK 时遇到问题。执行 .\gradlew assembleRelease 时出现以下错误:-

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeReleaseResources'.
> [drawable-mdpi-v4/node_modules_reactnativerouterflux_images_back_chevron] 
R:\Workings\lisecapps\androidrepo\test-react- 
native\venutest\android\app\src\main\res\drawable- 
mdpi\node_modules_reactnativerouterflux_images_back_chevron.png      
[drawable-mdpi-v4/node_modules_reactnativerouterflux_images_back_chevron] 
R:\Workings\lisecapps\androidrepo\test-react- 
emirnative\venutest\android\app\build\generated\res\react\release\drawable- 
mdpi-v4\node_modules_reactnativerouterflux_images_back_chevron.png: Error: 
Duplicate resources
[drawable-mdpi-v4/node_modules_reactnativerouterflux_images_menu_burger] 
R:\Workings\lisecapps\androidrepo\test-react-nat 
ive\venutest\android\app\src\main\res\drawable- 
mdpi\node_modules_reactnativerouterflux_images_menu_burger.png        
[drawable-mdpi-v4/node_modules_reactnativerouterflux_images_menu_burger] 
R:\Workings\lisecapps\androidrepo\test-react- 
native\venutest\android\app\build\generated\res\react\release\drawable-mdpi- 
v4\node_modules_reactnativerouterflux_images_menu_burger.png: Error: 
Duplicate resources

我尝试了以下方法来解决但仍然出现同样的错误:-

  • 尝试按照第一个答案here 中所述创建脚本,以避免重复复制资产 图片。
  • 删除了整个 app/build 文件夹

【问题讨论】:

  • 同样的问题。你是怎么过去的?
  • 我尝试了该解决方案,但它对我不起作用,因为我使用的是 react-native 0.61.1。请帮忙。

标签: android reactjs react-native


【解决方案1】:

您需要删除生成的资源/drawable 并再次生成。

rm -rf android/app/src/main/res/drawable-*
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/

然后再次编译androidreact-native run-android

【讨论】:

  • 有同样的错误。试过这个。没有运气。与以前完全相同的错误。
  • 这个是为我做的……我之前做过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 来解决另一个问题,结果证明是别的问题。我认为这是重复资产错误的原因。
【解决方案2】:

react.gradle 自动构建您的 javascript 并将您的 javascript 中导入的任何资源复制到构建文件夹,因此请确保不要手动调用 react-native bundle 并删除任何文件或文件夹为 src/main/res/drawable-*src/main/assets/*.bundle 并具有以下内容更改为您的app/bundle.gradle

project.ext.react = [
  entryFile      : "index.js", // or index.android.js
  bundleInRelease: true,
  bundleInDebug: true
]

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

注意:请注意部分 react-native 版本对本地 cli.js 有问题,请务必升级到较新版本或尝试添加以下配置

 project.ext.react = [
    // ...
    cliPath: "node_modules/react-native/local-cli/cli.js"
 ]

【讨论】:

    【解决方案3】:

    [0.57] 丑陋的解决方法

    如果您不想回滚 react-native 版本,您可以将 react.gradle 回滚到上一个工作版本。这对我有用。

    将git代码复制到node_modules/react-native/react.gradle

    https://github.com/facebook/react-native/blob/2d9e2f30e17b8e79f2c44ef533ecdd550671304c/react.gradle

    如果问题仍然存在,请尝试删除doLast 上的if (isAndroidLibrary)

    【讨论】:

      【解决方案4】:

      我正在使用:

      "react": "^16.5.2",
      "react-native": "0.57.1",
      

      我像这样修改了我的应用程序的 build.gradle

      ext.react = [
              entryFile: "index.js",
              bundleInRelease       : true,
              resourcesDirRelease   : "src/main/res"
      ]
      apply plugin: 'com.android.application'
      import com.android.build.OutputFile
      
      //using custom react gradle here to get around https://stackoverflow.com/questions/52464842/react-native-duplicate-resources
      apply from: "../react.gradle"
      //apply from: "../../node_modules/react-native/react.gradle"
      apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
      

      然后我的自定义 react.gradle 看起来像这样

      import org.apache.tools.ant.taskdefs.condition.Os
      
      def config = project.hasProperty("react") ? project.react : [];
      
      def cliPath = config.cliPath ?: "node_modules/react-native/local-cli/cli.js"
      def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
      def entryFile = config.entryFile ?: "index.android.js"
      def bundleCommand = config.bundleCommand ?: "bundle"
      
      // because elvis operator
      def elvisFile(thing) {
          return thing ? file(thing) : null;
      }
      
      def reactRoot = elvisFile(config.root) ?: file("../../")
      def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
      def bundleConfig = config.bundleConfig ? "${reactRoot}/${config.bundleConfig}" : null ;
      
      void runBefore(String dependentTaskName, Task task) {
          Task dependentTask = tasks.findByPath(dependentTaskName);
          if (dependentTask != null) {
              dependentTask.dependsOn task
          }
      }
      
      afterEvaluate {
          def isAndroidLibrary = plugins.hasPlugin("com.android.library")
          // Grab all build types and product flavors
          def buildTypes = android.buildTypes.collect { type -> type.name }
          def productFlavors = android.productFlavors.collect { flavor -> flavor.name }
      
          // When no product flavors defined, use empty
          if (!productFlavors) productFlavors.add('')
      
          productFlavors.each { productFlavorName ->
              buildTypes.each { buildTypeName ->
                  // Create variant and target names
                  def flavorNameCapitalized = "${productFlavorName.capitalize()}"
                  def buildNameCapitalized = "${buildTypeName.capitalize()}"
                  def targetName = "${flavorNameCapitalized}${buildNameCapitalized}"
                  def targetPath = productFlavorName ?
                          "${productFlavorName}/${buildTypeName}" :
                          "${buildTypeName}"
      
                  // React js bundle directories
                  def jsBundleDirConfigName = "jsBundleDir${targetName}"
                  def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
                          file("$buildDir/intermediates/assets/${targetPath}")
      
                  def resourcesDirConfigName = "resourcesDir${targetName}"
                  def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
                          file("$buildDir/intermediates/res/merged/${targetPath}")
                  def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
      
                  // Bundle task name for variant
                  def bundleJsAndAssetsTaskName = "bundle${targetName}JsAndAssets"
      
                  // Additional node and packager commandline arguments
                  def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
                  def extraPackagerArgs = config.extraPackagerArgs ?: []
      
                  def currentBundleTask = tasks.create(
                          name: bundleJsAndAssetsTaskName,
                          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.mkdirs()
                          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
      
                      // Set up the call to the react-native cli
                      workingDir reactRoot
      
                      // Set up dev mode
                      def devEnabled = !(config."devDisabledIn${targetName}"
                              || targetName.toLowerCase().contains("release"))
      
                      def extraArgs = extraPackagerArgs;
      
                      if (bundleConfig) {
                          extraArgs = extraArgs.clone()
                          extraArgs.add("--config");
                          extraArgs.add(bundleConfig);
                      }
      
                      if (Os.isFamily(Os.FAMILY_WINDOWS)) {
                          commandLine("cmd", "/c", *nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
                                  "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
                      } else {
                          commandLine(*nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
                                  "--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
                      }
      
                      enabled config."bundleIn${targetName}" ||
                              config."bundleIn${buildTypeName.capitalize()}" ?:
                              targetName.toLowerCase().contains("release")
      
                  }
      
                  // Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process
                  currentBundleTask.dependsOn("merge${targetName}Resources")
                  currentBundleTask.dependsOn("merge${targetName}Assets")
      
                  runBefore("process${flavorNameCapitalized}Armeabi-v7a${buildNameCapitalized}Resources", currentBundleTask)
                  runBefore("process${flavorNameCapitalized}X86${buildNameCapitalized}Resources", currentBundleTask)
                  runBefore("processUniversal${targetName}Resources", currentBundleTask)
                  runBefore("process${targetName}Resources", currentBundleTask)
                  runBefore("dataBindingProcessLayouts${targetName}", currentBundleTask)
              }
          }
      }
      

      【讨论】:

      • 你使用什么版本的 React 和 React Native?
      • "react": "^16.5.2", "react-native": "0.57.1​​",
      • 你是男人中的王者。谢谢!
      【解决方案5】:

      你可以尝试清理catch memory并重新安装节点模块

      watchman watch-del-all
      rm -rf node_modules && npm install
      rm -fr $TMPDIR/react-*
      npm cache clean
      npm start -- --reset-cache
      

      这对我有用。

      【讨论】:

        【解决方案6】:

        这对我有用:

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

        在我的项目中,构建失败,因为我的 Android 项目中有重复的资源。此行是删除重复资源所必需的。

        【讨论】:

          【解决方案7】:

          还有另一种方法可以解决此问题。对我来说,只需在我的项目的 android/build.gradle 中添加以下代码即可:

          subprojects {
              afterEvaluate {project ->
                  if (project.hasProperty("android")) {
                      android {
                          compileSdkVersion 27
                          buildToolsVersion "27.0.2"
                      }
                  }
              }
          }
          

          【讨论】:

            【解决方案8】:

            这很容易! 只需删除 app/src/main/res 下的 drawable 和 raw 文件夹

            【讨论】:

              【解决方案9】:

              试试这个:

              1. 删除 android/app 文件夹内的构建
              2. 删除 android 文件夹内的构建
              3. 运行 rm -rf $HOME/.gradle/caches/
              4. 打开 build.gradle --> android/app/build.gradle
              5. 评论此行

              //申请自:“../../node_modules/react-native/react.gradle”

              1. 从 assets 文件夹中删除 index.android.bundle 文件并使用 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

              2. 运行 react-native run-android 或者运行 react-native run-android --variant=release

              【讨论】:

                猜你喜欢
                • 2019-03-09
                • 1970-01-01
                • 2023-02-12
                • 2017-09-30
                • 2015-12-12
                • 2018-08-21
                • 1970-01-01
                • 1970-01-01
                • 2018-11-07
                相关资源
                最近更新 更多