web-dev-qa-db-fra.com

Réaction native erreur de fichier dupliqué Android lors de la génération apk

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.

39
Shongsu

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.

  1. Créer Android-react-gradle-fix fichier
  2. Créer un script Android-release-gradle-fix.js file
  3. Mettre à 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.

95
Nhan Cao

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.

27
MOSTRO

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

N'exécutez pas 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é.

13
Joshua Pinter

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

Pour moi, cela fonctionne pour supprimer le dossier: Android/build et exécuter à nouveau ./gradlew assembleRelease.

2
suther

Un moyen de supprimer l'erreur serait de:

  • placez vos images dans le dossier Android/app/src/main/res/drawable (créez un dossier «dessinable» s’il n’existe pas) 
  • supprimer tous les dossiers pouvant être dessinés avec des suffixes (par exemple, drawable-hdpi, drawable-mdpi, etc.)
  • ne pas regrouper les actifs (c'est-à-dire ne pas exécuter: réactif natif, bundle…)
  • exécuter Gradle’s assembleRelease

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:

  • ouvrez votre projet dans Android studio et accédez à: Android/app/src/main/res/drawable
  • faites un clic droit sur le dossier et choisissez: Nouveau> Importation en lots par dessin
  • sélectionner et configurer les éléments d'image à importer

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.

0
Richard Lovell

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

0
Rajesh Nasit