React Native Android Duplicate File Error When Generating APK

React Native : Error: Duplicate resources - Android

After trying a lot of solutions I found only Three solution is working. Here they are

Solution 1:

Clean the drawable folder from the terminal using Gradle. cd into the android folder, then run cmd ./gradlew clean

Solution 2:

After bundling delete the drawable folder from Android Studio. You could find this in android/app/src/main/res/drawable

Solution 3:

PLEASE DO NOT USE SOLUTION #2, AS PROPOSED BY THE ORIGINAL AUTHOR! All packages under node_modules are generated, and any changes you make will be lost when the react-native package is reinstalled / upgraded.

In this solution you no need to delete any drawable folder. Just add the following code in the react.gradle file which you could find under node_modules/react-native/react.gradle path

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

For reference I will add the full react.gradle file code here

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"
def reactRoot = file(config.root ?: "../../")
def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
def bundleConfig = config.bundleConfig ? "${reactRoot}/${config.bundleConfig}" : null ;

afterEvaluate {
android.applicationVariants.all { def variant ->
// Create variant and target names
def targetName = variant.name.capitalize()
def targetPath = variant.dirName

// React js bundle directories
def jsBundleDir = file("$buildDir/generated/assets/react/${targetPath}")
def resourcesDir = file("$buildDir/generated/res/react/${targetPath}")

def jsBundleFile = file("$jsBundleDir/$bundleAssetName")

// Additional node and packager commandline arguments
def nodeExecutableAndArgs = config.nodeExecutableAndArgs ?: ["node"]
def extraPackagerArgs = config.extraPackagerArgs ?: []

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

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

// 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${variant.buildType.name.capitalize()}" ?:
targetName.toLowerCase().contains("release")
}

// Expose a minimal interface on the application variant and the task itself:
variant.ext.bundleJsAndAssets = currentBundleTask
currentBundleTask.ext.generatedResFolders = files(resourcesDir).builtBy(currentBundleTask)
currentBundleTask.ext.generatedAssetsFolders = files(jsBundleDir).builtBy(currentBundleTask)

// registerGeneratedResFolders for Android plugin 3.x
if (variant.respondsTo("registerGeneratedResFolders")) {
variant.registerGeneratedResFolders(currentBundleTask.generatedResFolders)
} else {
variant.registerResGeneratingTask(currentBundleTask)
}
variant.mergeResources.dependsOn(currentBundleTask)

// packageApplication for Android plugin 3.x
def packageTask = variant.hasProperty("packageApplication")
? variant.packageApplication
: tasks.findByName("package${targetName}")

def resourcesDirConfigValue = config."resourcesDir${targetName}"
if (resourcesDirConfigValue) {
def currentCopyResTask = tasks.create(
name: "copy${targetName}BundledResources",
type: Copy) {
group = "react"
description = "copy bundled resources into custom location for ${targetName}."

from resourcesDir
into file(resourcesDirConfigValue)

dependsOn(currentBundleTask)

enabled currentBundleTask.enabled

}

packageTask.dependsOn(currentCopyResTask)
}

def currentAssetsCopyTask = tasks.create(
name: "copy${targetName}BundledJs",
type: Copy) {
group = "react"
description = "copy bundled JS into ${targetName}."

if (config."jsBundleDir${targetName}") {
from jsBundleDir
into file(config."jsBundleDir${targetName}")
} else {
into ("$buildDir/intermediates")
into ("assets/${targetPath}") {
from jsBundleDir
}

// Workaround for Android Gradle Plugin 3.2+ new asset directory
into ("merged_assets/${targetPath}/merge${targetName}Assets/out") {
from jsBundleDir
}
}

// mergeAssets must run first, as it clears the intermediates directory
dependsOn(variant.mergeAssets)

enabled currentBundleTask.enabled
}

packageTask.dependsOn(currentAssetsCopyTask)
}
}

Credit:
ZeroCool00
mkchx

React Native Android Duplicate file error when generating apk

Give some tips for you, hope it's work.

Update with "react": "16.7.0", "react-native": "0.57.8"

Custom node_modules/react-native/react.gradle to solve the Duplicate file error perfectly. Add following code into currentBundleTask's creation block (after doFirst block)

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);
}
}
moveFunc.curry("ldpi").call()
moveFunc.curry("mdpi").call()
moveFunc.curry("hdpi").call()
moveFunc.curry("xhdpi").call()
moveFunc.curry("xxhdpi").call()
moveFunc.curry("xxxhdpi").call()
}

You can create script to do it automatically.

  1. Create android-react-gradle-fix file
  2. Create script android-release-gradle-fix.js file
  3. Update package.json file:

    "scripts": {
    "postinstall": "node ./android-release-gradle-fix.js"
    },

That's it! Run npm install to get awesome.

Note: If you run npm install on ci like jenkins, you may get error: postinstall: cannot run in wd %s %s (wd=%s) node => just use npm install --unsafe-perm instead

React Native 0.57.1 Android Duplicate Resources

Here is the simple solution :

  1. Delete build inside android/app folder
  2. Delete build inside android folder
  3. run rm -rf $HOME/.gradle/caches/
  4. Open build.gradle --> android/app/build.gradle
  5. comment this line

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


  1. Delete index.android.bundle file from assets folder and re-create using 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. run react-native run-android Or
    run react-native run-android --variant=release

Happy Coding..

Generate an apk failed on React native

This problem ocurrs because the project builded duplicates files.

To resolve it, you need delete the files inside of res folder.

Delete drawable folder and raw folder.

Your project directory will be like that:

Sample Image



Related Topics



Leave a reply



Submit