Open In App

Manifest Merger Fails with Multiple Errors in Android Studio

Last Updated : 22 Aug, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

An Android Studio project generally contains more than one Android Manifest.xml file. They are provided by the main sources set, imported libraries, and build variants. However, we know that the Android App Bundle file can contain only one AndroidManifest.xml file. So, the Gradle build merges all these manifest files into a single file. This process is carried out while building the application.

What is Manifest Merger?

The manifest merger tool plays an important role in combining all XML elements from each file. It follows merge heuristics and obeys all the merge preferences with special XML attributes defined by the user. The job of the merger tool is to logically match all the XML elements in one manifest with their respective elements in other manifests.

What is Merge Conflict?

A merge conflict occurs while merging whenever the value of any attribute is different in the two Manifest files. However, if an element from the lower-priority manifest does not match any elements in the high-priority manifest, then it is added to the merged manifest. And, if there is a matching element, then the merger tool combines all attributes from each into the same element.

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

How to Resolve Merge Conflict?

Sometimes, it is possible that the higher-priority manifest is dependent on the default value of an attribute, but this value is not declared in the file. As all the unique elements are combined into the same element, a Merge Conflict may occur. Therefore, it is advisable not to be dependent on the default attribute values. For an instance, if the higher priority manifest uses “standard” as the default value for the android:launchMode attribute, without declaring it in the file and the lower-priority manifest assigns a different value to the same attribute, that value overrides the default value. Hence, it is applied to the merged manifest file. Therefore, the value of each attribute should be explicitly defined as per requirement. 

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

Merge Rule Markers

These are XML attributes that can be used to express the user’s preference about how to solve merge conflicts or remove unnecessary elements and attributes. A marker can be applied to either an entire element or to a specific attribute. When merging two manifest files, the merger tool looks for these markers in the higher-priority manifest file. All markers belong to the Android tools namespace. Hence, they must be declared in the <manifest> element as shown:

XML




   package="com.example.myapp"


Node Markers

To apply a merge rule to an entire XML element (to all attributes in a given manifest element and to all its child tags), use the following attributes:

  1. tools:node=”merge”: Merge all attributes in this tag and all nested elements when there are no conflicts using the merge conflict heuristics. This is the default behavior for elements.
  2. tools:node=”merge-only-attributes”: Merge attributes in this tag only; do not merge nested elements.
  3. tools:node=”remove”: Remove this element from the merged manifest. Although it seems like you should instead just delete this element, using this is necessary when you discover an element in your merged manifest that you don’t need, and it was provided by a lower-priority manifest file that’s out of your control (such as an imported library).
  4. tools:node=”removeAll”: Like tools:node=”remove”, but it removes all elements matching this element type (within the same parent element).
  5. tools:node=”replace”: Replace the lower-priority element completely. That is, if there is a matching element in the lower-priority manifest, ignore it and use this element exactly as it appears in this manifest.
  6. tools:node=”strict”: Generate a build failure any time this element in the lower-priority manifest does not exactly match it in the higher-priority manifest (unless resolved by other merge rule markers). This overrides the merge conflict heuristics. For example, if the lower-priority manifest simply includes an extra attribute, the build fails (whereas the default behavior adds the extra attribute to the merged manifest).

This creates a manifest merge error. The two manifest elements cannot differ at all in strict mode. So you must apply other merge rule markers to resolve these differences.

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.

Attribute Markers

Instead, apply a merge rule only to specific attributes in a manifest tag, use the following attributes. Each attribute accepts one or more attribute names (including the attribute namespace), separated by commas.

  1. tools:remove=”attr, …”: Remove the specified attributes from the merged manifest. Although it seems like you could instead just delete these attributes, it’s necessary to use this when the lower-priority manifest file does include these attributes and you want to ensure they do not go into the merged manifest.
  2. tools:replace=”attr, …”: Replace the specified attributes in the lower-priority manifest with those from this manifest. In other words, always keep the higher-priority manifest’s values.
  3. tools:strict=”attr, …”: Generate a build failure any time these attributes in the lower-priority manifest do not exactly match them in the higher-priority manifest. This is the default behavior for all attributes, except for those with special behaviors as described in the merge conflict heuristics. This creates a manifest merge error. You must apply other merge rule markers to resolve the conflict.

Marker Selector

If you want to apply the merge rule markers to only a specific imported library, add the tools:selector attribute with the library package name. For example, with the following manifest, the remove merge rule is applied only when the lower-priority manifest file is from the com.example.lib1 library. If the lower-priority manifest is from any other source, the remove merge rule is ignored. If it is used with one of the attribute markers, then it applies to all attributes specified in the marker.

Some Useful Tricks to Solve Merge Errors

  • Add the overrideLibrary attribute to the <uses-sdk> tag. This may be useful when we try to import a  library with a minSdkVersion value that is higher than the manifest file and an error occurs. The overrideLibrary tag lets the merger tool ignore this conflict. Thus, the library is imported and the app’s minSdkVersion value also stays lower.
  • The minSdkVersion of the application and all the used modules should be the same.
  • In addition to it, the build version of the app and modules should be exactly similar, i.e. the app’s build.gradle and the manifest.xml files should possess the same configurations.
  • Check for duplicity in the permissions and activity attributes in the manifest file.
  • Check for the versions of added dependencies. They should be of the same version.
  • Also, don’t forget to remove the reference of any deleted activity in the manifest file.
  • A few errors may occur due to label, icon, etc. tags in the manifest file. Try adding the following labels to resolve the issue:
    • Add the xmlns:tools line in the manifest tag.
    • Add tools:replace= or tools:ignore= in the application tag.


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads