Ошибка слияния манифеста с несколькими ошибками в Android Studio

Опубликовано: 24 Января, 2023

Проект Android Studio обычно содержит более одного файла Android Manifest.xml. Они предоставляются основным набором исходников, импортированными библиотеками и вариантами сборки. Однако мы знаем, что файл Android App Bundle может содержать только один файл AndroidManifest.xml. Итак, сборка Gradle объединяет все эти файлы манифеста в один файл. Этот процесс выполняется при создании приложения.

Что такое манифестное слияние?

Инструмент слияния манифестов играет важную роль в объединении всех элементов XML из каждого файла. Он следует эвристике слияния и подчиняется всем предпочтениям слияния со специальными XML-атрибутами, определенными пользователем. Задача инструмента слияния — логически сопоставить все элементы XML в одном манифесте с соответствующими элементами в других манифестах.

Что такое конфликт слияния?

Конфликт слияния возникает при слиянии всякий раз, когда значение любого атрибута отличается в двух файлах манифеста. Однако если элемент из манифеста с более низким приоритетом не соответствует элементам в манифесте с высоким приоритетом, он добавляется в объединенный манифест. И, если есть соответствующий элемент, то инструмент слияния объединяет все атрибуты каждого в один и тот же элемент.

Note: Use the Merged Manifest view to preview the results of your merged manifest and find conflict errors.

Как разрешить конфликт слияния?

Иногда возможно, что манифест с более высоким приоритетом зависит от значения атрибута по умолчанию, но это значение не объявлено в файле. Поскольку все уникальные элементы объединяются в один элемент, может возникнуть конфликт слияния. Поэтому желательно не зависеть от значений атрибутов по умолчанию. Например, если манифест с более высоким приоритетом использует «стандарт» в качестве значения по умолчанию для атрибута android:launchMode, не объявляя его в файле, а манифест с более низким приоритетом присваивает другое значение тому же атрибуту, это значение переопределяет значение по умолчанию. ценность. Следовательно, он применяется к объединенному файлу манифеста. Поэтому значение каждого атрибута должно быть явно определено в соответствии с требованием.

Note: Default values for each attribute are documented in the Manifest reference.

Объединить маркеры правил

Это XML-атрибуты, которые можно использовать для выражения предпочтения пользователя относительно того, как разрешать конфликты слияния или удалять ненужные элементы и атрибуты. Маркер может применяться как ко всему элементу, так и к определенному атрибуту. При объединении двух файлов манифеста инструмент слияния ищет эти маркеры в файле манифеста с более высоким приоритетом. Все маркеры принадлежат пространству имен инструментов Android. Следовательно, они должны быть объявлены в элементе <manifest>, как показано ниже:

XML




   package="com.example.myapp"

Маркеры узлов

Чтобы применить правило слияния ко всему элементу XML (ко всем атрибутам в данном элементе манифеста и ко всем его дочерним тегам), используйте следующие атрибуты:

  1. tools:node="merge": объединить все атрибуты в этом теге и все вложенные элементы, если нет конфликтов, используя эвристику конфликта слияния. Это поведение по умолчанию для элементов.
  2. tools:node="merge-only-attributes": объединить атрибуты только в этом теге; не объединяйте вложенные элементы.
  3. tools:node="remove": удалить этот элемент из объединенного манифеста. Хотя кажется, что вместо этого вы должны просто удалить этот элемент, использовать это необходимо, когда вы обнаружите элемент в объединенном манифесте, который вам не нужен, и он был предоставлен файлом манифеста с более низким приоритетом, который находится вне вашего контроля (например, как импортированная библиотека).
  4. tools:node="removeAll": аналогично tools:node="remove", но удаляет все элементы, соответствующие этому типу элемента (в пределах одного и того же родительского элемента).
  5. tools:node="replace": полностью заменить элемент с более низким приоритетом. То есть, если в манифесте с более низким приоритетом есть соответствующий элемент, игнорируйте его и используйте этот элемент точно так, как он отображается в этом манифесте.
  6. tools:node=”strict”: генерировать сбой сборки каждый раз, когда этот элемент в манифесте с более низким приоритетом не совпадает точно с ним в манифесте с более высоким приоритетом (если только это не разрешено другими маркерами правила слияния). Это переопределяет эвристику конфликта слияния. Например, если манифест с более низким приоритетом просто включает дополнительный атрибут, сборка завершится ошибкой (в то время как поведение по умолчанию добавляет дополнительный атрибут в объединенный манифест).

Это создает ошибку слияния манифеста. Два элемента манифеста вообще не могут различаться в строгом режиме. Таким образом, вы должны применить другие маркеры правил слияния, чтобы устранить эти различия.

Note: For app modules, tools merge markers are removed after the merge; however, for library modules, tools merge markers are not removed after the merge and may affect merges in a downstream module.

Маркеры атрибутов

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

  1. tools:remove="attr, …": удалить указанные атрибуты из объединенного манифеста. Хотя кажется, что вы могли бы просто удалить эти атрибуты, это необходимо использовать, когда файл манифеста с более низким приоритетом включает эти атрибуты, и вы хотите убедиться, что они не вошли в объединенный манифест.
  2. tools:replace="attr, …": заменить указанные атрибуты в манифесте с более низким приоритетом атрибутами из этого манифеста. Другими словами, всегда сохраняйте значения манифеста с более высоким приоритетом.
  3. tools:strict="attr, …": генерировать сбой сборки каждый раз, когда эти атрибуты в манифесте с более низким приоритетом не совпадают точно с ними в манифесте с более высоким приоритетом. Это поведение по умолчанию для всех атрибутов, за исключением тех, которые имеют особое поведение, как описано в эвристике конфликта слияния. Это создает ошибку слияния манифеста. Вы должны применить другие маркеры правила слияния, чтобы разрешить конфликт.

Селектор маркеров

Если вы хотите применить маркеры правил слияния только к определенной импортированной библиотеке, добавьте атрибут tools:selector с именем пакета библиотеки. Например, в следующем манифесте правило удаления слияния применяется только в том случае, если файл манифеста с более низким приоритетом находится в библиотеке com.example.lib1. Если манифест с более низким приоритетом получен из любого другого источника, правило слияния удаления игнорируется. Если он используется с одним из маркеров атрибутов, то он применяется ко всем атрибутам, указанным в маркере.

Некоторые полезные приемы для устранения ошибок слияния

  • Добавьте атрибут overrideLibrary в тег <uses-sdk>. Это может быть полезно, когда мы пытаемся импортировать библиотеку со значением minSdkVersion, превышающим значение файла манифеста, и возникает ошибка. Тег overrideLibrary позволяет инструменту слияния игнорировать этот конфликт. Таким образом, библиотека импортируется, а значение minSdkVersion приложения также остается ниже.
  • MinSdkVersion приложения и всех используемых модулей должны совпадать.
  • Кроме того, версия сборки приложения и модулей должна быть абсолютно одинаковой, т.е. файлы build.gradle и manifest.xml приложения должны иметь одинаковые конфигурации.
  • Проверьте наличие дубликатов разрешений и атрибутов действий в файле манифеста.
  • Проверьте версии добавленных зависимостей. Они должны быть одной версии.
  • Кроме того, не забудьте удалить ссылку на любое удаленное действие в файле манифеста.
  • Некоторые ошибки могут возникать из-за тегов меток, значков и т. д. в файле манифеста. Попробуйте добавить следующие ярлыки, чтобы решить проблему:
    • Добавьте строку xmlns:tools в тег манифеста.
    • Добавьте tools:replace= или tools:ignore= в тег приложения.