wake-up-neo.com

Reagieren Sie bei der Generierung von apk auf native Android-Duplikate

Wenn ich versuche, Android-apk mit ./gradlew installRelease zu generieren, erhalte ich diese Fehlermeldung in der Konsole:

~/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.

Ich habe Build->Clean Project über Android Studio ausprobiert und erneut ./gradlew installRelease ausgeführt. es hat auch nicht funktioniert. 

Ich habe auch versucht, den Ordner build zu löschen, aber es hilft auch nicht.

39
Shongsu

Gib ein paar Tipps für dich, hoffe es funktioniert.

Update mit "reagieren": "16.7.0", "reagieren-native": "0.57.8"

Benutzerdefinierte node_modules/rease-native/react.gradle -Daten, um den Fehler bei doppelter Datei perfekt zu lösen. Fügen Sie dem Erstellungsblock von currentBundleTask folgenden Code hinzu (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()
}

Sie können ein Skript erstellen, um dies automatisch durchzuführen.

  1. Erstellen Sie Android-react-gradle-fix file
  2. Erstellen Sie das Skript Android-release-gradle-fix.js file
  3. package.json-Datei aktualisieren:

    "Skripte": { "postinstall": "Knoten ./Android-release-gradle-fix.js" },

Das ist es! Führe npm install aus, um großartig zu werden.

Hinweis: Wenn Sie npm install auf ci wie jenkins ausführen, wird möglicherweise ein Fehler angezeigt: postinstall: cannot run in wd %s %s (wd=%s) node => verwenden Sie stattdessen npm install --unsafe-perm

95
Nhan Cao

Entfernen Sie die Dateien, die Sie möglicherweise haben:

Android/app/src/main/res/drawable-mdpi/
Android/app/src/main/res/drawable-xhdpi/
Android/app/src/main/res/drawable-xxhdpi/

Build erneut ausführen. Das Problem wurde für mich behoben.

27
MOSTRO

Zum Zeitpunkt des Schreibens haben die neueren Versionen von React Native (> 0.57.0) den Gradle-Wrapper-Level auf 4,4 und das Gradle-Plugin auf 3.1.4 erhöht, wie durch das changelog angezeigt wird. Dies bewirkt, dass der Gradle-Build-Prozess die Ergebnisse von AAPT, die jetzt required sind, in einem anderen Verzeichnis als zuvor speichert.

In Bezug auf Nhan Cao s awesome Workaround müssen wir eine geringfügige Modifikation vornehmen, um doppelte Ressourcenkollisionen zu vermeiden, da er auf das alte Verzeichnis und nicht auf das generated-Verzeichnis der App verweist. Durch das Ändern des Zielverzeichnisses, in dem diese doppelten Dateien nach dem Generieren der Ressourcen zusammengeführt werden, können wir die Ressourcen weiterhin verwenden.

Der vorhandene react.gradle bezieht sich auf den folgenden Pfad:

$buildDir === <project-working-directory>/Android/app/build

Die doppelten Dateipfade können zwischen:

file("$buildDir/../src/main/res/drawable-${resSuffix}")
file("$buildDir/generated/res/react/release/drawable-${resSuffix}")

Als Problemumgehung können wir die Lösung von Nhan wie folgt aktualisieren (stellen Sie sicher, dass Sie diese nach der Deklaration von currentBundleTask in react.gradle in doFirst aufnehmen:

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

Führen Sie react-native bundle nicht vor ./gradlew assembleRelease aus.

Ich selbst habe vor der Ausführung von react-native bundle./gradlew assembleRelease ausgeführt.

Ich habe bei einem meiner Assets eine ähnliche Fehlermeldung erhalten. 

Bei der Ausgabe von ./gradlew assembleRelease konnte ich feststellen, dass das JS-Bundle von selbst erstellt wird (dank apply from: "../node_modules/react-native/react.gradle" in Ihrer build.gradle-Datei), so dass es nicht notwendig war, react-native bundle vorher manuell auszuführen.

Wenn ich react-native bundle einfach nicht ausgeführt habe, bevor ./gradlew assembleRelease ausgeführt wurde, hat alles super funktioniert.

Ich habe die Release-APK getestet, und das JS-Bundle wird gut geladen, einschließlich aller Images. 

Meine einzige Sorge ist, ob die Quellkarten --sourcemap-output (für Bugsnag) erstellt werden. Wenn nicht, bin ich sicher, dass es eine Möglichkeit gibt, ./gradlew assembleRelease auch diese generieren zu lassen. Ich habe es gerade noch nicht getestet.

13
Joshua Pinter

Damit mein Build für React Native 0.57.5 funktioniert, habe ich die Antwort von Mapsy mit einer geringfügigen Verbesserung verwendet. Ich musste in der Lage sein, für verschiedene Geschmacksrichtungen zu bauen, und generell versuche ich, hardcoding Dinge zu vermeiden. Beim Durchschauen meiner react.gradle-Datei habe ich festgestellt, dass folgende Variable definiert wurde:

def resourcesDir = file("$buildDir/generated/res/react/${targetPath}")

Anstatt den Build-Typ/Flavour im Pfad wie folgt fest zu codieren:

File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");

Ich habe stattdessen die Variable resourcesDir verwendet, um den Pfad originalDir wie folgt festzulegen:

File originalDir = file("${resourcesDir}/drawable-${resSuffix}");

Daher sieht meine doLast so aus:

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

Für mich funktioniert es, den Ordner zu entfernen: Android/build und ./gradlew assembleRelease erneut auszuführen.

2
suther

Eine Möglichkeit, den Fehler zu beheben, wäre:

  • legen Sie Ihre Bilder in den Ordner Android/app/src/main/res/drawable ab (erstellen Sie einen "drawable" -Ordner, falls noch keiner existiert). 
  • alle zeichnerischen Ordner löschen, die Suffixe enthalten (d. h. drawable-hdpi, drawable-mdpi usw.)
  • bündeln keine Assets (d. h. nicht ausführen: reaktives Bundle ...)
  • führen Sie die AssembleRelease von Gradle aus

Dies ist jedoch keine ideale Lösung, da jedes Bild nur eine Auflösung für alle Gerätegrößen hat. Bei Bildern, die für ein Gerät zu groß sind, bleiben die Downscaling-Werte für das Gerät erhalten, was zu Problemen mit der Downloadgröße und -geschwindigkeit führt. Bei Bildern, die für ein Gerät zu klein sind, führt dies zu einer Verschlechterung der Bildqualität. 

Eine praktische Lösung, die ich gefunden habe, ist die Verwendung eines Android Studio-Plugins namens Android Drawable Importer. So verwenden Sie es nach der Installation:

  • Öffnen Sie Ihr Projekt in Android Studio und navigieren Sie zu: Android/App/src/main/res/drawable
  • klicken Sie mit der rechten Maustaste auf den Ordner und wählen Sie: Neu> Stapelweise Zeichnungsimport
  • image-Assets für den Import auswählen und konfigurieren

Das Plugin übernimmt die Erstellung der zeichnerischen Ordner und die korrekte Bildgröße. Nachdem Sie Ihr Bild importiert haben, sollten Sie in der Lage sein, assleiseRelease von Gradle ohne den Fehler der doppelten Ressourcen auszuführen.

0
Richard Lovell

Was für mich funktionierte, war einfach das Hinzufügen dieses zusätzlichen Befehls in package.json und verwende das zum Bauen:

    "Android-build-release": "cd ./Android && rm -rf app/src/main/res/drawable* && ./gradlew app:assembleRelease",

0

Versetzen Sie Ihr Projekt in die Quellcodeverwaltung. Verwenden Sie Gitlance Plugin in VS Code-Tool. In den Bühnenänderungen können Sie neu generierte Bilddateien anzeigen. Alles löschen und erneut buid. Das Problem wurde behoben

0
Rajesh Nasit