Android Studio: дубликаты файлов, скопированных в APK META-INF/DEPENDENCIES при компиляции

Я экспортировал свой проект из Eclipse и импортировал его в Android Studio, используя инструкции по этой ссылке: http://developer.android.com/sdk/installing/migrate.html

Когда я создаю, у меня есть ошибка:

Duplicate files copied in APK META-INF/DEPENDENCIES

После поиска я нашел решение: add

packagingOptions {
    exclude 'META-INF/DEPENDENCIES'
}

в build.gradle. И это работает!

Но я не понимаю, почему у меня была эта ошибка и почему я должен был применить это исправление. Может кто-нибудь объяснить?

Ответ 1

В версиях Android Gradle вам не разрешается включать один и тот же файл с одним и тем же путем более одного раза в выходной файл. В вашей сборке было два файла META-INF/DEPENDENCIES, которые поступали из разных мест. Поскольку вам вообще не нужен этот файл в вашем приложении, проще всего сказать, что система сборки полностью игнорирует его, что и делает эта директива exclude.

Также существует директива pickFirst, чтобы сообщить системе сборки одну из копий; там крошечное количество деталей в том, что в Android Gradle плагин 0.7.0: "дублировать файлы во время упаковки APK" .

Android-сборки в Gradle довольно строгие в отношении дубликатов файлов, что может затруднить жизнь. Там аналогичная проблема, если вы включаете один и тот же Java-класс более одного раза, где вы получаете ошибку "Несколько файлов dex files" (см. Несколько файлов dex определяют Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat) для типичного примера).

Другие системы сборки более снисходительны. В Java типично, что если вы включаете один и тот же класс более одного раза в путь к классам, например, первая копия, которую он видит, является той, которая использовалась; дубликаты после этого игнорируются. С этим легче справляться, но у него есть пара проблем. Самый большой из них заключается в том, что могут быть тонкие ошибки, если несколько разных версий файла ползутся в сборку без вашего ведома - может быть трудно понять, что происходит. Когда вы это выясните, вы можете, как правило, решить это, жонглируя порядком, в котором все включено, чтобы убедиться, что тот, который вы хотите, делает его конечным результатом, но в очень сложных сборках этого может быть трудно достичь, и это может случиться, что выполнение, казалось бы, несвязанных вещей, таких как включение новых библиотек в ваш проект, может нарушить порядок и привести к большому сожалению.

По этой причине Gradle имеет философию не полагаться на упорядочение вещей, чтобы определить "победителей" в игре по разрешению дубликатов, и это заставляет разработчика делать все зависимости явными. Внедрение Android своей системы сборки поверх Gradle следует этой философии.

Ответ 2

В то время как ответ Скотта Барты верен, не хватает простого и общего решения: просто добавьте

android {
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
}

в ваш build.gradle, чтобы игнорировать эти дубликаты.

Ответ 3

Простейшим решением является добавление

 packagingOptions {
    pickFirst  'META-INF/*'
}

в ваш build.gradle в разделе Android.

Ответ 4

В случае, если кто-либо из этих проблем загружает новый .apk в Google Play Store после обновления Android Studio;

нажмите V1 Jar Signature not Full Apk Signature при создании нового Apk со старым Keystore

V1 Jar Signature

введите описание изображения здесь

Ответ 5

Самый простой способ решить эту проблему - использовать подстановочный знак, поэтому вам не нужно вручную объявлять каждый конфликт в конфликте.

packagingOptions {
    pickFirst  '**'
}