Reputation: 4650
I was trying to create a release apk file from Android but when I create a release apk with PNG image I'm getting Duplicate Resource
error. Initially I thought this is happening because I made a mistake in the existing project but when I created a new project with a single Image
component itself I'm getting the Duplicate Resource
error. Here are the steps I followed
react-native init demo
PNG
image inside the assets folder.Image
component with the above PNG
image.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/
Generate Signed APK
from Android Studio
.This will throw the following error:
[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
BUILD FAILED in 22s
Note: When you generate a release apk
without any PNG image you will not get any error, it will create you the release apk
.
Here are the other files code.
App.js
import React, {Component} from 'react';
import {Platform, StyleSheet, Image, View} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Image source={require('./assets/mario.png')} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
package.json
{
"name": "errorCheck",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.6.0-alpha.8af6728",
"react-native": "0.57.4"
},
"devDependencies": {
"babel-jest": "23.6.0",
"jest": "23.6.0",
"metro-react-native-babel-preset": "0.49.0",
"react-test-renderer": "16.6.0-alpha.8af6728"
},
"jest": {
"preset": "react-native"
}
}
Any solution for this?
Update:
Here are the other details
classpath 'com.android.tools.build:gradle:3.1.4'
ext {
buildToolsVersion = "27.0.3"
minSdkVersion = 16
compileSdkVersion = 27
targetSdkVersion = 26
supportLibVersion = "27.1.1"
}
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
Tried with Android Studio 3.0, 3.0.1, 3.1, 3.1.4 & 3.2
Upvotes: 119
Views: 175895
Reputation: 163
This issue also comes up when you have two files with the same name but different file extensions, for example, ball.png ball.jpeg.
A simpler alternative to the above solution would be renaming the asset file names.
Upvotes: 0
Reputation: 1
for my case, I used the same filename in gif image and png image. rename them solved me.
Upvotes: 0
Reputation: 6272
This solution we work for user who are using github or any other version control system.
The reason for this issue was github. if we clean the project then and create a release build it was crashing due to missing resources. on the other hand if i run this command.
npx 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/build/intermediates/res/merged/release/ && cd android && ./gradlew assembleRelease && cd ..
it well create the issue duplicate resources.
so before creating a release version of your appplication. clean you project with commad gradlew clean
and delete the file android\app\src\main\assets\index.android.bundle
. now run this commnad
npx 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
after running this command open vs code and delete all the newly added files except index.android.bundle
now you can create a release of you app. it will work fine
Upvotes: 3
Reputation: 111
Good day all. It may be late but I encountered a strange situation while bundling/assembling my project on RN (0.71.x). Using the information from your project asset [drawable-mdpi-v4/assets_mario].
I discovered that when bundling, the configuration removes the extensions reference from the filename. So if you have assets_mario.jpg and assets_mario.png being bundled, the final configuration reference for both becomes [drawable-mdpi-v4/assets_mario] with two instances and thus, duplicate resources violation.
Somehow, all your assets must have unique names. Check on this as well.
Upvotes: 3
Reputation: 882
Open android studio and check res
and res(generated)
folders. For me in res
folder was duplicated files in raw
folder.
I manually deleted raw
folder from res
and see BUILD SUCCESSFUL
Upvotes: 0
Reputation: 71
was error with release build /android/app/src/main/res/raw/app.json
:
[raw/app] /android/app/build/generated/res/react/release/raw/app.json: Error: Duplicate resources
deleted /android/app/src/main/res/raw/app.json
then ran ./gradlew clean
in android
folder
and then ran ./gradlew bundleRelease
Upvotes: 5
Reputation: 336
tolotrasmile's answer worked for me.
I included it in my little bash script that I run whenever I want to build & install Android
cd "$PROJECT_DIRECTORY"
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
cd ..
rm -rf "$PROJECT_DIRECTORY"/android/app/src/main/res/drawable-*
rm -rf "$PROJECT_DIRECTORY"/android/app/src/main/res/raw
cd "$PROJECT_DIRECTORY"/android/
./gradlew clean
./gradlew assembleRelease
cd ../../
adb install -r "$PROJECT_DIRECTORY"/android/app/build/outputs/apk/release/app-release.apk
Upvotes: 7
Reputation: 134
In my case, it worked after adding a few lines to Jaffrey's Answer
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);
}
}
Upvotes: 5
Reputation: 3955
The accepted answer will work, however it does not take into account that modifying a node package means that if you update your change will be lost (as well as being against best-practices, you should extend the module somehow).
This is originally from React-native android release error: duplicate resource
Create folder fixAndroid
in the android
folder of your project ({project-root}/android/fixAndroid
).
Create file android-gradle-fix
in the fixAndroid
folder of your project ({project-root}/android/fixAndroid/android-gradle-fix
).
doLast {
def moveFunc = { resSuffix ->
File originalDir = file("${resourcesDir}/drawable-${resSuffix}")
if (originalDir.exists()) {
File destDir = file("${resourcesDir}/drawable-${resSuffix}-v4")
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
android-release-fix.js
in the fixAndroid
folder you created:const fs = require('fs')
try {
var curDir = __dirname
var rootDir = process.cwd()
var file = `${rootDir}/node_modules/react-native/react.gradle`
var dataFix = fs.readFileSync(`${curDir}/android-gradle-fix`, 'utf8')
var data = fs.readFileSync(file, 'utf8')
var doLast = "doLast \{"
if (data.indexOf(doLast) !== -1) {
throw "Already fixed."
}
var result = data.replace(/\/\/ Set up inputs and outputs so gradle can cache the result/g, dataFix);
fs.writeFileSync(file, result, 'utf8')
console.log('Android Gradle Fixed!')
} catch (error) {
console.error(error)
}
"postinstall": "node ./android/fixAndroid/android-release-fix.js"
This will find and insert content of “android-gradle-fix” file into node_modules/react-native/react.gradle.
npm install
from the root of your project.rm -rf android/app/src/main/res/drawable-*
from the root of your project.Now you can bundle the release with either React Native at the console or Android Studio:
React Native command line
cd {project-root}/android
./gradlew/bundleRelease
Android Studio
Upvotes: 15
Reputation: 277
who are facing the same issue in RN! I think it's absolutely awful that this issue stands here for so long time already, but I want to share the way to solve it after investigation of different solutions.
Jeffrey Rajan is absolutely right about the possible solutions here https://stackoverflow.com/a/53260522/1611414
I think it's super bad to change react.gradle
file in node_modules
and it leads to many many different issues with the maintenance of this RN project. So I would recommend to chose the first option - to use bash command to remove that folder before running build.
I want to share what I've done in my project and maybe you can reuse the same approach:
In ./package.json
:
scripts: {
"build": "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/
&& rm -rf ./android/app/src/main/res/drawable-mdpi/
&& rm -rf ./android/app/src/main/res/raw/",
"release": "yarn build && cd ./android && ./gradlew bundleRelease"
}
and the release is running by doing yarn release
.
These lines are important:
&& rm -rf ./android/app/src/main/res/drawable-mdpi/
&& rm -rf ./android/app/src/main/res/raw/
they remove duplicated resources from the build
step before bundleRelease
is running. The solution is tested with RN 0.57, 0.58, 0.59 and 0.60
Enjoy!
Upvotes: 11
Reputation: 149
for latest version of React-Native and gradle, you don't need to bundle your assets. Once you are done with the code, just cd into the android folder and run:
./gradlew assembleRelease
The assets are automatically bundled while the above command is been executed. The duplicate resources error shows up because you have explicitly bundled before and running the above command bundles again hence the error.
Upvotes: 10
Reputation: 7447
For generating debug apk
"debug-build": "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/ && cd android && ./gradlew assembleDebug && cd .."
For generating release apk
"release-build": "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/build/intermediates/res/merged/release/ && rm -rf android/app/src/main/res/drawable-* && rm -rf android/app/src/main/res/raw/* && cd android && ./gradlew assembleRelease && cd .."
Works fine for my react-native >= 0.61.2 project by using the above code on my scripts section of package.json file.
Upvotes: 70
Reputation: 4650
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 thereact-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
Upvotes: 137
Reputation: 1580
A slight addition: sometimes you end up with a "raw" in the resources folder. That has to go too. So a slight modification to the existing react.gradle script:
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()
}
Upvotes: 0
Reputation: 5109
This issue comes after you run 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
So only thing you want to do is remove the resources files which builds with it.
If you use git
,
stage index.android.bundle
and discard other new resource files.
Upvotes: 0
Reputation: 344
Accepted answer's solution 1 will work but it will add some more things to your assets.
Solution 1:
Clean the drawable folder from the terminal using Gradle. cd into the android folder, then run cmd ./gradlew clean
This will solve the initial problem of old code rendering but will create another issue usually: the issue of duplicate resources.
Check your androids res folder there will be added additional assets in your mipmap filders and res folder, delete all the additional added assets from the folders and run the release version of app ad you will be good to go.
Upvotes: 0
Reputation: 1
It's not needed to add any code in the react-native module.
By default, the app/build.gradle set the property bundleInRelease
as true. This means that if you run the react native bundle
before the build, you will get this error.
To fix this issue, make sure that your app/build.gradle has the following code:
project.ext.react = [
bundleInRelease: false
]
You can find more details in: https://github.com/react-native-community/cli/blob/master/docs/commands.md
Upvotes: -1
Reputation: 41
If the above answers are not working and if the issue is similar to the below error
> Task :app:mergeReleaseResources FAILED
ERROR: [drawable-mdpi-v4/node_modules_reactnative_libraries_newappscreen_components_logofgdsfsdfsdfds]
/Users/emmsdan/Repo/untitledApp/android/app/src/main/res/drawable-mdpi/node_modules_reactnative_libraries_newappscreen_components_logofgdsfsdfsdfds.png
[drawable-mdpi-v4/node_modules_reactnative_libraries_newappscreen_components_logofgdsfsdfsdfds]
/Users/emmsdan/Repo/untitledApp/android/app/build/generated/res/react/release/drawable-mdpi/
node_modules_reactnative_libraries_newappscreen_components_logofgdsfsdfsdfds.png: Resource and asset merger: Duplicate resources
Not the most elegant solution but this worked for me.
Delete this
rm -rf rmnode_modules/react-native/Libraries/NewAppScreen
I had similar issues, even on a newly created react-native app. Deleting NewAppScreen and everywhere it was called fixed it for me.
Upvotes: 1
Reputation: 4651
My version react native is: 0.66.3 , I had fix trought commands:
rm -rf ./android/app/src/main/res/drawable-*
rm -rf ./android/app/src/main/res/raw
Then run :
./gradlew clean
Finally: Generate Signed Bundle from Android Studio and works.
Upvotes: 2
Reputation: 3270
(UPDATED)
This solution works for me
rm -rf ./android/app/src/main/res/drawable-*
rm -rf ./android/app/src/main/res/raw
In my case, the build failed because there are duplicated resources in my Android project (in Android folder), these two lines are necessary to remove duplicated resources, that's all.
Upvotes: 169
Reputation: 14611
I had also this problem and to solve it, I have deleted resource folders and used gradlew clean
.
I ended up with this Windows cmd script for compiling my app:
@echo off
call 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
rmdir android\app\src\main\res\drawable-hdpi /s/q
rmdir android\app\src\main\res\drawable-mdpi /s/q
rmdir android\app\src\main\res\drawable-xhdpi /s/q
rmdir android\app\src\main\res\drawable-xxhdpi /s/q
rmdir android\app\src\main\res\drawable-xxxhdpi /s/q
rmdir android\app\src\main\res\raw /s/q
cd android
call gradlew clean
REM call gradlew assembleRelease
call gradlew bundle
cd ..
dir /o:d android\app\build\outputs\apk\release
dir /o:d android\app\build\outputs\bundle
Upvotes: 1
Reputation: 5968
for me go to dir: android/app/src/main/assets/fonts
check .ttf files you expect, delete .ttf of vector icons
Upvotes: 1
Reputation: 1419
In my case, raw directory was containing some duplicates. So, I have to add a different function for that as well, name of added function is moveFuncRaw below worked perfectly for me.
doLast {
// Address issue #22234 by moving generated resources into build dir so they are in one spot, not duplicated
def moveFuncRaw = { dirName ->
File originalDir = file("$buildDir/generated/res/react/release/${dirName}");
if (originalDir.exists()) {
File destDir = file("$buildDir/../src/main/res/${dirName}");
ant.move(file: originalDir, tofile: destDir);
}
}
// Address issue #22234 by moving generated resources into build dir so they are in one spot, not duplicated
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()
moveFuncRaw.curry("raw").call()
}
One more thing to realize that doLast do not gets called every time as there could be some conditions on it like in my case there were, so you have to call separately to get it executed.
Upvotes: 0
Reputation: 11
Spent ages on this! None of the proposed solutions were an immediate fix for me.
So I moved out all the dirs that were getting mentioned in the "duplicate resource" error message:
mv ./android/app/src/main/res/drawabl* /tmp
mv ./android/app/src/main/res/raw /tmp
then I ran a
./gradlew clean
then I ran a build:
/gradlew bundleRelease
the build was giving me a couple of errors along the lines of 'could not find a specific file in a specific place', so for each of these files I found them in the tmp/drawable folders and copied them to the exact path that the error message said it expected them to be e.g (you'll have to customise this according to the error message you get):
cp /tmp/drawable-mdpi/launch_screen.png app/src/main/res/drawable/
then:
./gradlew clean
/gradlew bundleRelease
And it finally buily successfully
Upvotes: 1
Reputation: 2392
None of the suggested solutions works for me
In my case it was related to .gradle
folder. Before getting this error i have moved the folder to another disk, but some files failed to copy to the destination folder.
I just cut the old folder and merge it with the destination folder.
Upvotes: 0
Reputation: 336
inside src -> main -> res folder then
react-native bundle --dev false --platform android --entry-file index.js --bundle-output ./android/app/src/main/assets/index.android.bundle --assets-dest ./android/app/src/main/res_temp
Upvotes: 12
Reputation: 1
The solutions like patching the react.gradle file may work but they are just workarounds. The real solution lies in figuring out the problem.
If its only happening while creating release build then chances are you're bundling separately. If you're upgrading from older versions of react native which didn't have a react.gradle file you'd have to bundle separately and then do 'cd android && ./gradlew assembleRelease' but with the introduction of react.gradle the bundling process has now been taken care by the react.gradle file, so don't bundle separately just run 'cd android && ./gradlew clean && ./gradlew assembleRelease' to build the release apk.
If this happens in debug also then chances are some generated assets or all of the generated assets have been pushed and currently reside in your directory. So i would suggest just delete all of them from the respective directory and if they are tracked by git try adding them back one by one. We had some assets starting with src_assets_blahblah which we had to delete since they were already getting generated during the build process.
Upvotes: 0
Reputation: 31
I am using react-native 0.63.2. I also faced this issue and tried editing react.gradle, deleted resources/drawable and all. But at last cleaning gradle and running the command gradlew assembleRelease
worked.
I didn't run the react-native bundle command separately. gradlew assembleRelease
is running the react-native bundle and building apk itself.
Upvotes: 1
Reputation: 429
Try to use another directory for assets destination (for example res_temp).
react-native bundle --dev false --platform android --entry-file index.js --bundle-output ./android/app/src/main/assets/index.android.bundle --assets-dest ./android/app/src/main/res_temp
I am also adding res_temp in gitignore. Tested in Gradle 6.0.1 and RN 0.62.2
Upvotes: 3
Reputation: 1226
Solution.
I just clean gradlew
and starts working no need to change anything in.
/node_modules/react-native/react.gradle
Steps
1) cd android && ./gradlew clean && cd ..
2) react-native run-android
"dependencies": {
"react": "16.11.0",
"react-native": "0.62.2",
}
Upvotes: 2