Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android, Gradle, product flavors and the manifest

In build.gradle, I have product flavors set up:

productFlavors
{
    AlternateFlavour
    {
        applicationId "com.myapp.alternateflavour"
    }
}

Then in the sourceSets section, I use different resource, assets and manifest directories for those flavours:

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
    }

    AlternateFlavour {
        manifest.srcFile 'manifest-tmp/AlternateFlavour/AndroidManifest.xml'
        java.srcDirs = ['src']
        res.srcDirs = ['res-tmp/AlternateFlavour']
        assets.srcDirs = ['assets-tmp/AlternateFlavour']
        }
   }

OK so far.

In that manifest being used by the flavor, which is in part automatically generated, I have:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myapp.myapp"
    android:versionCode="1010001"
    android:versionName="V1.1.0.1" >

but in the original manifest in the root project is as follows:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myapp.myapp"
    android:versionCode="1010000"
    android:versionName="V1.1.0.DEBUG" >

This causes Gradle to fail:

Error:
    Attribute manifest@versionCode value=(1010001) from AndroidManifest.xml:4:5-28
    is also present at AndroidManifest.xml:4:5-28 value=(1010000).
Attributes of <manifest> elements are not merged.

Why is it trying to merge with the original manifest at all, when I've specified it should look elsewhere?

And how can I stop this?

I expect some will question why I'm doing it this way at all, or indeed why I'm not using the suggested flavor project structure. Well, I need a normal manifest to use outside of Gradle, e.g. for deploying from Eclipse (one thing at a time please!) and I also need versions to be injected by the build process.

like image 760
Rob Pridham Avatar asked Mar 04 '16 12:03

Rob Pridham


People also ask

What are Buildtypes and product Flavours in gradle and what can you use them for?

Once the new project is created, by default it consists of two build types/variants - debug, release. Debug is the build type that is used when we run the application from the IDE directly onto a device. A release is the build type that requires you to sign the APK.

What is product flavors in Android?

Product flavours lets you create multiple variants of an android app while using a single codebase. To create product flavours you need to define rules in the build.

What is the manifest in Android?

The manifest file describes essential information about your app to the Android build tools, the Android operating system, and Google Play.

How do I get the current flavor in gradle?

gradle. getStartParameter(). getTaskRequests(). toString() contains your current flavor name but the first character is capital.


1 Answers

Why is it trying to merge with the original manifest at all, when I've specified it should look elsewhere?

You said the flavor manifest is elsewhere. The manifest merger process merges all relevant manifests:

  • main
  • the build type
  • the product flavor(s)
  • libraries

The manifest in main is always relevant.

And how can I stop this?

You don't, insofar as the manifest in main is always relevant.

The best solution, in general, is to get rid of versionCode and versionName from all manifests, and set them in build.gradle, where you have full programmatic control.

The next-best solution is to move the versionCode and versionName out of the main manifest into the product flavor that you're not showing here. I have never seen anyone create just one product flavor, as AFAIK it's pointless — you can only ever build that one product flavor (as AFAIK there are no flavorless builds once you introduce flavors). Product flavors usually come in groups of 2+ (e.g., the google flavor that uses Play Services and the standalone flavor that doesn't). If the values in main are really for the non-AlternateFlavour flavor, move your main version... stuff there.

Beyond that, you're welcome to review the documentation on the manifest merger process to see if you can put in the right directives to get what you want.

like image 173
CommonsWare Avatar answered Sep 25 '22 10:09

CommonsWare