[Deprecated]
This post is now deprecated, the Manifest Merger has changed since my first post. You can find more about this on the android developers site.
Manifest file & Gradle
If you started using Android Studio and implicitly Gradle, or you just started using Gradle with other IDEs (like Intellij for example), then maybe you would like to know how to merge the manifest files. This is needed especially when your project uses multiple modules. So if you someday will need to achieve this and don’t know how to do this kind of merge, you should follow the steps below. The steps are not very complicated, we tried to make them as simple as possible and give explanations in order to let anyone understand what they have to do, so we hope this tutorial will help you in a way or another. So, let’s start!
Here is a way of making Gradle merge the manifest files of multiple modules by your rule:
Import the XML schema
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
These lines are the first two lines from the xml document. The first one, already exists in your manifest file. The second one (xmlns:tools), must be written by you. You can copy from this post and paste it in your code, under the default schema, just like in the above example.
Add your rule
Next thing you have to do is to add your rule (override or remove).
tools:merge="override"
OR
tools:merge="remove"
Where to put it?
Maybe you wonder where to put it, right? :) Well, there are seven places where you could put the tag.
- application tag
- activity tag
- receiver tag (this one is used for broadcast receivers)
- service tag
- provider tag
- instrumentation tag
- permission tag
But, we gave an example for almost each of these places, so you can choose what you need.
- application tag
<application android:name="ro.funcode.ApplicationProvider" tools:merge="override"></application>
- activity tag
<activity android:name="com.google.android.gms.ads.AdActivity" tools:merge="override" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
- broadcast receiver tag
<receiver android:name="ro.funcode.receiver" tools:merge="override"></receiver>
- service tag
<service android:name="ro.funcode.service" tools:merge="override"></service>
- provider tag
<provider android:name="ro.funcode.provider" tools:merge="override" android:authorities="ro.funcode.provider.auth"></provider>
- instrumentation tag
- permissions tag
Explanation
As you could see at the beginning of this post, there are two types of rules: override and remove. We will try to explain first, the latest (the remove tag).
So, tool:merge=”remove” means to remove a node and prevent merging. What does this actually mean? Well, it’s not just that the node from the libraries is not merged, but the element is also removed from the main manifest. So you can use this when you have a weak tag and you don’t want the merge to keep it.
The second rules, tool:merge=”override” means to ignore what comes from libraries and only keep the version from the main manifest. Due to these rules no conflict can be generated.
Unfortunately there is no way at the moment to use these rules to handle the uses-sdk tag merge. So far the uses-sdk tag is just checked against each module and if minSdkVersion doesn’t match, an exception is thrown. Maybe in the near future there will be a way to merge the uses-sdk too. But until then, we have to work with what we have :).
In addition to this page, the source of the documentation is the merge class itself and you can see it here.
The example above might also help you get rif of the following error:
Error:Execution failed for task ':MainModule:processDebugManifest'.
> Manifest merging failed. See console for more info.
I hope this post was helpful for you.
Update:
I have uploaded a simple example of what you can do using the merge attribute.
The code can be found here.
The project will be used to show other gradle use cases but the code used by this one can be found in the MainModule Manifest file and also in the LibraryModuleA Manifest file.
The case exemplified here is when one has an activity in a library project. The Activity is blocked to a landscape orientation and is wanted to be on portrait when used from his module.
To achieve that, I just overridden the activity tag from the library manifest into the main module manifest. Also added the “merge” attribute to tell gradle that I need the activity declaration from the main manifest and not the one from the library.
To see exactly what I wanted to do, please run the app as it is and open the LibraryActivity by pressing the button on the screen. Observe the Activity’s orientation and go back to the source code.
Finally find the MainModule Manifest file and comment the overridden activity tag, run the app and notice the difference.
I know this is not the best example but I think it should be just great for the start! ;)