web-dev-qa-db-ja.com

React Native Android apkを生成する際の重複ファイルエラー

./gradlew installReleaseを使用してAndroid apkを生成しようとすると、コンソールに次のエラーが表示されます。

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

Android St​​udioでBuild->Clean Projectを試し、再度./gradlew installReleaseを実行しました。それも機能しませんでした。

また、buildフォルダーを削除しようとしましたが、それも役に立ちません。

49
Shongsu

あなたにいくつかのヒントを与え、それがうまくいくことを願っています。

「react」で更新:「16.7.0」、「react-native」:「0.57.8」

カスタムnode_modules/react-native/react.gradle重複ファイルエラーを完全に解決します。次のコードを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()
}

自動的に実行するスクリプトを作成できます。

  1. Android-react-gradle-fix ファイルを作成します
  2. スクリプトの作成 Android-release-gradle-fix.js ファイル
  3. package.jsonファイルを更新します。

    「スクリプト」:{"postinstall": "node ./Android-release-gradle-fix.js"}、

それでおしまい! npm installを実行して、すばらしい結果を得てください。

注: jenkinsのようなciでnpm installを実行すると、エラーが発生する場合があります:postinstall: cannot run in wd %s %s (wd=%s) node =>代わりにnpm install --unsafe-permを使用します

119
Nhan Cao

持っている可能性のあるファイルを削除します。

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

ビルドを再度実行します。これにより、問題が修正されました。

33
MOSTRO

執筆時点で、React Nativeの最新バージョン(> 0.57.0)は、 changelogで示されるように、Gradleラッパーレベルを4.4に、Gradleプラグインを3.1.4に増やしました 。これには、Gradleビルドプロセスに、以前とは異なるディレクトリ内に、現在requiredであるAAPTの結果を保存させる効果があります。

Nhan Caoawesome workaround に関しては、重複したリソースの衝突を防ぐためにわずかな変更を加える必要があります。アプリのgeneratedディレクトリ。リソースが生成された後にこれらの重複ファイルがマージされるターゲットディレクトリを変更することで、リソースを重複除去できます。

既存のreact.gradleは、以下のパスを参照します。

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

重複するファイルパスは、次の間に表示されます。

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

回避策として、次のようにNhanのソリューションを更新できます(react.gradlecurrentBundleTaskの宣言の後、doFirst内にこれを必ず含めてください:

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

react-native bundleの前に./gradlew assembleReleaseを実行しないでください。

私にとっては、react-native bundleを実行する前に./gradlew assembleReleaseを実行していました。

アセットの1つで同様の重複エラーメッセージが表示されていました。

./gradlew assembleReleaseの出力を見ると、JSバンドルを単独でビルドしている(apply from: "../node_modules/react-native/react.gradle"ファイルのbuild.gradleのおかげです)ので、手動でreact-native bundleを手動で実行する必要はありませんでした。

react-native bundleを実行する前に単に./gradlew assembleReleaseを実行しなかった場合、すべてがうまくいきました。

リリースAPKをテストし、すべての画像を含むJSバンドルが正常にロードされました。

私の唯一の懸念は、ソースマップ--sourcemap-output(Bugsnag用)が作成されるかどうかです。そうでない場合は、./gradlew assembleReleaseでそれらを生成する方法があると確信しています。まだテストしていません。

14
Joshua Pinter

ビルドをReact Native 0.57.5で機能させるために、 Mapsy の回答にマイナーな機能強化を加えました。複数のフレーバー向けにビルドできるようにする必要があり、一般的にハードコーディングを避けようとしています。 react.gradleファイルを調べると、次の変数が定義されていることがわかりました。

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

したがって、次のようなパスでビルドタイプ/フレーバーをハードコーディングする代わりに:

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

代わりにresourcesDir変数を使用して、次のようにoriginalDirパスを設定しました。

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

その結果、doLastは次のようになります。

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

私にとっては、Android/buildフォルダーを削除し、./gradlew assembleReleaseを再度実行することです。

2
suther

エラーを削除する方法は次のとおりです。

  • 画像をAndroid/app/src/main/res/drawableフォルダーに配置します(「描画可能」フォルダーが存在しない場合は作成します)
  • サフィックス(つまり、drawable-hdpi、drawable-mdpiなど)を持つすべてのドロアブルフォルダーを削除します。
  • アセットをバンドルしない(つまり、実行しない:反応ネイティブバンドル…)
  • gradleのassembleReleaseを実行します

ただし、これは理想的なソリューションではありません。各画像には、すべてのデバイスサイズに対して1つの解像度しかありません。デバイスに対して大きすぎる画像の場合、デバイスにダウンスケーリングが残り、ダウンロードサイズと速度の問題が発生します。また、デバイスに対して小さすぎる画像の場合、画像品質が低下します。

私が見つけた便利なソリューションの1つは、Android Drawable ImporterというAndroid St​​udioプラグインを使用することです。インストール後に使用するには:

  • Android studioでプロジェクトを開き、Android/app/src/main/res/drawableに移動します
  • フォルダーを右クリックして、「新規」>「バッチ描画可能インポート」を選択します
  • インポートする画像アセットを選択して構成する

プラグインは、描画可能なフォルダの生成と正しい画像サイズを処理します。画像をインポートすると、重複リソースエラーなしでGradleのassembleReleaseを実行できるはずです。

0
Richard Lovell

プロジェクトをソース管理に配置します。 VS Codeツールでgitlanceプラグインを使用します。ステージ変更で新しく生成された画像ファイルを確認できます。すべてを削除し、再びbuidすることで問題を修正しました

0
Rajesh Nasit