Lorsque j'essaie de générer un apk Android en utilisant ./gradlew installRelease
, j'obtiens cette erreur dans la console:
~/React-Native/mockingbird/Android/app/build/intermediates/res/merged/release/drawable-mdpi-v4/src_resources_img_loading.gif: error: Duplicate file.
~/React-Native/mockingbird/Android/app/build/intermediates/res/merged/release/drawable-mdpi/src_resources_img_loading.gif: Original is here. The version qualifier may be implied.
J'ai essayé Build->Clean Project
via Android Studio et j'ai à nouveau lancé ./gradlew installRelease
; cela n'a pas fonctionné non plus.
En outre, j'ai essayé de supprimer le dossier build
, mais cela n'aide pas non plus.
Donner des conseils pour vous, espérons que cela fonctionne.
Mise à jour avec "react": "16.7.0", "react-native": "0.57.8"
Personnalisation node_modules/react-native/react.gradle pour résoudre parfaitement erreur de fichier en double Ajouter le code suivant dans le bloc de création de currentBundleTask (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()
}
Vous pouvez créer un script pour le faire automatiquement.
Android-react-gradle-fix
fichierAndroid-release-gradle-fix.js
fileMettre à jour le fichier package.json
:
"scripts": { "postinstall": "noeud ./Android-release-gradle-fix.js" },
C'est tout! Exécutez npm install
pour obtenir un résultat fantastique.
Note: Si vous exécutez npm install
sur ci comme jenkins, vous risquez d'obtenir l'erreur: postinstall: cannot run in wd %s %s (wd=%s) node
=> utilisez simplement npm install --unsafe-perm
à la place.
Supprimez les fichiers que vous pourriez avoir sur:
Android/app/src/main/res/drawable-mdpi/
Android/app/src/main/res/drawable-xhdpi/
Android/app/src/main/res/drawable-xxhdpi/
Exécutez à nouveau la compilation, cela a résolu le problème pour moi.
Au moment de la rédaction de ce manuel, les versions les plus récentes de React Native (> 0.57.0) ont augmenté le niveau de wrapper Gradle à 4.4 et le plug-in Gradle à 3.1.4, comme indiqué par le changelog . Cela a pour effet de faire que le processus de construction de Gradle stocke les résultats de AAPT, qui sont maintenant required, dans un répertoire différent de celui utilisé précédemment.
Pour ce qui est de la solution de contournement de Nhan Cao 's awesome , nous devons apporter une légère modification pour éviter les collisions de ressources en double, car elle semble pointer vers l'ancien répertoire et non vers le répertoire generated
. En modifiant le répertoire cible où ces fichiers en double sont fusionnés après la génération des ressources, nous pouvons toujours dédoubler les ressources.
Le react.gradle
existant fait référence au chemin ci-dessous:
$buildDir === <project-working-directory>/Android/app/build
Les chemins de fichiers en double peuvent apparaître entre:
file("$buildDir/../src/main/res/drawable-${resSuffix}")
file("$buildDir/generated/res/react/release/drawable-${resSuffix}")
En guise de solution de contournement, nous pouvons mettre à jour la solution de Nhan comme suit (veillez à l'inclure dans la variable currentBundleTask
après la déclaration de doFirst
dans 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()
}
react-native bundle
avant ./gradlew assembleRelease
.Pour ma part, j’exécutais react-native bundle
avant d’exécuter ./gradlew assembleRelease
.
Je recevais un message d'erreur en double similaire avec l'un de mes actifs.
En regardant la sortie ./gradlew assembleRelease
, je peux dire que cela construit le bundle JS lui-même (grâce à apply from: "../node_modules/react-native/react.gradle"
dans votre fichier build.gradle
), de sorte qu'il n'était pas nécessaire d'exécuter manuellement react-native bundle
à la main.
Si je n’ai tout simplement pas exécuté react-native bundle
avant d’exécuter ./gradlew assembleRelease
, tout a bien fonctionné.
J'ai testé la version APK et le paquet JS se charge très bien, y compris toutes les images.
Ma seule préoccupation est de savoir si les cartes sources --sourcemap-output
(pour Bugsnag) seront créées. Sinon, je suis sûr qu'il existe un moyen de faire en sorte que ./gradlew assembleRelease
les génère également. Je ne l'ai pas encore testé.
Afin de pouvoir utiliser ma construction pour React Native 0.57.5, j'ai utilisé la réponse de Mapsy avec une amélioration mineure. Je devais être capable de construire pour plusieurs goûts et en général, j'essaie d'éviter le codage en dur. En parcourant mon fichier react.gradle
, j’ai trouvé que la variable suivante était définie:
def resourcesDir = file("$buildDir/generated/res/react/${targetPath}")
Donc, au lieu de coder en dur le type de construction/saveur dans le chemin comme ceci:
File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
J'ai plutôt utilisé la variable resourcesDir
pour définir le chemin originalDir
comme suit:
File originalDir = file("${resourcesDir}/drawable-${resSuffix}");
En conséquence, ma doLast
ressemble à ceci:
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()
}
Pour moi, cela fonctionne pour supprimer le dossier: Android/build
et exécuter à nouveau ./gradlew assembleRelease
.
Un moyen de supprimer l'erreur serait de:
Cependant, ce n'est pas une solution idéale car chaque image n'aura qu'une résolution pour toutes les tailles de périphériques. Pour les images trop volumineuses pour un périphérique, cela entraîne une réduction de la taille de celui-ci et entraîne des problèmes de taille et de vitesse de téléchargement. Pour les images trop petites pour un périphérique, la qualité de l'image diminue.
Une solution pratique que j'ai trouvée consiste à utiliser un plugin Android Studio appelé Android Drawable Importer. Pour l'utiliser après son installation:
Le plugin gérera la génération des dossiers pouvant être dessinés et les tailles d'image correctes. Une fois que vous avez importé votre image, vous devriez pouvoir exécuter la commande assembleRelease de Gradle sans l’erreur de ressources en double.
Mettez votre projet sur le contrôle de source. Utilisez le plugin gitlance dans VS Outil de code. Vous pouvez voir les fichiers d’images nouvellement générés lors des changements de phase . tout effacer et à nouveau ça corrige le problème