升级到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
我尝试了以下方法来解决,但仍然是相同的错误:-
答案 0 :(得分:3)
react.gradle自动构建您的JavaScript并将所有在JavaScript中导入的资源复制到构建文件夹,因此请确保不要手动调用react-native bundle
并删除任何文件或文件夹为src/main/res/drawable-*
和{{1 }},并对您的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"
有问题,请确保升级到新版本或尝试添加以下配置
cli.js
答案 1 :(得分:2)
您需要删除生成的资源/可绘制对象,然后重新生成。
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/
然后再次编译android react-native run-android
答案 2 :(得分:1)
[0.57]变通办法
如果您不想回滚react-native版本,只需将react.gradle回滚到上一个工作版本。那对我有用。
将git代码复制到node_modules/react-native/react.gradle
https://github.com/facebook/react-native/blob/2d9e2f30e17b8e79f2c44ef533ecdd550671304c/react.gradle
如果问题仍然存在,请尝试删除if (isAndroidLibrary)
上的doLast
。
答案 3 :(得分:1)
您可以尝试清除捕获内存并重新安装节点模块
watchman watch-del-all
rm -rf node_modules && npm install
rm -fr $TMPDIR/react-*
npm cache clean
npm start -- --reset-cache
这对我有用。
答案 4 :(得分:0)
我正在使用:
"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)
}
}
}
答案 5 :(得分:0)
还有另一种方法可以解决此问题。对我来说,只需在项目的android / build.gradle中添加以下代码即可:
subprojects {
afterEvaluate {project ->
if (project.hasProperty("android")) {
android {
compileSdkVersion 27
buildToolsVersion "27.0.2"
}
}
}
}
答案 6 :(得分:0)
这对我有用:
rm -rf ./android/app/src/main/res/raw
在我的项目中,构建失败,因为我的Android项目中存在重复的资源。此行对于删除重复的资源是必需的。
答案 7 :(得分:0)
很容易! 只需删除app / src / main / res下的drawable和raw文件夹