7

I am trying to set up flavours, so I can build different apps in he same project that share the same code... But I am not sure I am doing it fully correct...

I have created a project called com.sharedid.app in folder W:\android-studio-projects\sharedid\

For this I have

1) Created AndroidManifest.xml in W:\android-studio-projects\sharedid\app\src\main looking like this:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.sharedid.app"
  android:versionCode="1"
  android:versionName="1.0"
>
<activity android:name="com.shared.app.SharedMain" android:label="@string/MicMainName" >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>  
</manifest>

2) In W:\android-studio-projects\sharedid\app\src\main\java ... I have all .java files

3) In W:\android-studio-projects\sharedid\app\src\main\res I have all shared and/or dummy resources

For my flavour I have:

1) I have created AndroidManifest.xml in W:\android-studio-projects\sharedid\app\src\myflavour (this file is what defines everything - it is unqiue for each flavour)

2) In W:\android-studio-projects\sharedid\app\src\myflavour\res I have a single folder drawable-hdpi conttaining variois graphics

3) In W:\android-studio-projects\sharedid\app\src\myflavour\assets I have all sorts of data, configuration and graphic files for that specifc app. (read by the code at runtime)

4) In *W:\android-studio-projects\sharedid\app\src\myfavlour* I have the following AndroidManifest.xml file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.myflavour.app"
  android:versionCode="2"
  android:versionName="2.0"
>
<uses-sdk
  android:minSdkVersion="9"
  android:targetSdkVersion="17" 
/>
  <uses-feature android:glEsVersion="0x00020000" android:required="true" />

<application
  android:allowBackup="true"
  android:icon="@drawable/app_logo__forlarge"
  android:label="@string/MicAppName"
  android:theme="@style/MicTheme_myflavour"
  android:name="com.shared.app.MicApp"
>
<provider
  android:name="android.support.v4.content.FileProvider"
  android:authorities="com.myflavour.app.fileprovider"
  android:grantUriPermissions="true"
  android:exported="false">
  <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_filepaths" />
</provider>
<activity android:name="com.shared.app.SharedMain" android:label="@string/MicMainName" >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>        
<activity>...more...</activity>        
</application>
</manifest>

Here's how "Gradle Scripts" - "Build Gradle" (Module: app) looks like:

apply plugin: 'com.android.application'

android {
    signingConfigs {
    }
    compileSdkVersion 21
    buildToolsVersion '21.1.2'
    defaultConfig {
        applicationId "com.sharedid.app"
        minSdkVersion 9
        targetSdkVersion 17
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
        }
    }
    repositories {
        maven { url "https://jitpack.io" }
    }     
    productFlavors {
      myflavour {
          applicationId "com.myflavour.app"
      }
    }
    sourceSets {
      main {
        manifest.srcFile 'src/main/AndroidManifest.xml'
      }
      myflavour {
        manifest.srcFile 'src/myflavour/AndroidManifest.xml'
      }
    }           
}    
dependencies {
    compile 'com.android.support:support-v4:18.0.0'
    compile 'com.google.android.gms:play-services:+'
    compile 'com.android.support:appcompat-v7:21.1.2'
    compile 'com.github.PhilJay:MPAndroidChart:v2.0.8'
}

My problem is this

When I in "build variants" select "module=app" and "build-variant=com.myflavour.appDebug" and click "Run > Debug..." I get a dialog that states: "Error: Default activity not found"

From my studies of flavours I should not need to define sourcesets paths since I use the default conventenion of files for flavours... If I am right abnout that - then why does it not see the Androidmanifest file for the flavour selected?

Links for reference I base my understanding on:

Additional troubleshooting

In my attempt to find the root of this problem, I begun to suspect manifest merging was not working. The reason for this suspicion was that if I ignored the error about no activity and tried to push the compiled app out on the mobile, I would get a warning about the version number being smaller than the one installed on the mobile - clear indication wrong manifest file was being used.

So i have also tried to delete src/main/AndroidManifest.xml which results in error:

A problem was found with the configuration of task ':app:checkmyflavourDebugManifest'. File W:\android-studio-projects\sharedid\src\main\AndroidManifest.xml' specified for property 'manifest' does not exist

This leads me to believe Android Studio is completely ignoring that I am actually specifying it to use another manifest file... And the same time though it would seem i an building the correct variation build.

I would apreciate any comment/analysis on this - even if just to confirm my thinking of the cause

Screenshot of my current setup

(in this screenshot I have experiemented deleting main/shared androidmanifest file, but otherwise it complete)

Latest update

I conclude flavors is not working / my gradle setup must be wrong. If I e.g. select building variation myflavourDebug Android studio does not use the manifest file defined in gradle. This alone should be enough to conclude where the problem relies.

Maybe my gradle file is wrong somehow, I don't know, but I have taken great care in getting i right. If someone posts an asnwer while bounty is active I will try hurry and assign it.

Tom
  • 3,587
  • 9
  • 69
  • 124
  • I think the AndroidManifest needs to state any classes containing activities. – jrsall92 Nov 17 '15 at 14:02
  • Each flavour has its own AndroidManifest has so. Here's link to Google's own documentaion about how manifest files are supposed to merge: https://developer.android.com/tools/building/manifest-merge.html - maybe I have misundestood it though – Tom Nov 17 '15 at 14:27
  • Your manifest file should have activity class but i dont see it in manifest file. What is your activity class name? You should add it to manifest file in application tags. – alican akyol Nov 17 '15 at 15:41
  • I have now included the manifest file of my flavour... Is that the one you want to see? Or do you mean the shared manifest should include a dummy acivity class? – Tom Nov 17 '15 at 15:59
  • I have also tried insert the activity code in the shared androidmanifest file - no difference. Also i have tried "hardcode" paths to the manifest files iin my build gradle. – Tom Nov 18 '15 at 01:34
  • I think you should have one Main Activity in the project. Override it in the other flavors if you want. – Joaquin Iurchuk Nov 19 '15 at 21:37
  • @joaquin Currently they just delcare the same activity. If you think it will make a change to make the flavours a descendant (with no new code beyond that), I will try that? (Is hat correctly understood?) Do you suggest that because it might solve androidmanifest merge problem? (I think here may be a deeper problem since it also does not get version number correct, so I don't think it actually does any merge whatsoever at all when I build - too many things not working each indiciating no merge has taken place. But my analysis may be flawed) – Tom Nov 19 '15 at 22:59
  • Tried lots of different things and while certain combination may appear to work, I then get runtime errors like this: "unable to start activity ComponentInfo{com.myflavour.app/com.shared.app.SharedMain}: java.lang.NullPointerException" – Tom Nov 25 '15 at 16:45
  • For wha it is worth: I conclude flavors is not working like I thought / my gradle setup must be wrong. If I e.g. select building variation myflavourDebug Android studio does not use the manifest file defined in gradle. This alone should be enough to conclude where the problem relies and I have also seen other indication showing something similar. – Tom Nov 26 '15 at 04:19

3 Answers3

4

I think the problem is here:

applicationId "com.myflavour.app"

You define your applicationIs as com.myflavour.app in your build.gradle. In your AndroidManifest, you specifiy

<activity android:name="com.shared.app.SharedMain"
    android:label="@string/MicMainName" >

as your main Activity. Your main activity should be named after your applicationId, if I'm not wrong. So basically, you should try to change either your manifest to state your activity as com.myflavour.app and arrange your packaging accordingly, or you could just use the same applicationId for your flavour.

Benjamin Scharbau
  • 2,028
  • 1
  • 16
  • 33
  • In all my past apps my main activity has been named dfferently than the package id... – Tom Nov 20 '15 at 12:04
  • Also, the point behind flavours as far as I can tell is to use the same activity across multiple flavours with different application ids, so the names will never match? – Tom Nov 20 '15 at 13:08
2

to use Flavours It's not required to create Manifest files for every of them. Just put all your classes in src/mani/AndroidManifest.xml file. If you still wish to use both files remove conflicts by not overriding "intent-filter" block:

<intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Use it only once.

And finally, you can find a lot useful information on http://developer.android.com/tools/building/manifest-merge.html

Fast quote from there:

During the build process, the manifest merge process stores a record of each merge transaction in the manifest-merger--report.txt file in the module build/outputs/logs folder. A different log file is generated for each of the module's build variants.

vitalii
  • 443
  • 6
  • 10
  • Okay, so I put everything I can into main manifest. But what about "package" in the manifest file? (My problem is I do no think merge seems to work since I can see they are not properly merged. However, i will still try do as you suggest and report back) – Tom Nov 20 '15 at 12:03
  • I assume "provider" entries still belong in the flavour manifests. But how do I handle information like this android:theme="@style/...." I had hoped I could simply override/merge android manifests in each flavour? – Tom Nov 20 '15 at 12:47
  • Tried lots of different things and while certain combination may appear to work, I then get runtime errors like this: "unable to start activity ComponentInfo{com.myflavour.app/com.shared.app.SharedMain}: java.lang.NullPointerException". I guess somethng goes haywire. In the past I copy pasted coded between my apps, so I know individually they work. I will continue trying – Tom Nov 25 '15 at 16:46
  • From "manifest-merger--report.txt" one can see it completely ignores the AndroidManifest.xml the flavour has (and which is defined in the gradle) - this supports my own findinds that Android Studio is ignoring it – Tom Nov 26 '15 at 04:21
  • Tom show me please the error log from manifest-merger--report.txt file in the module build/outputs/logs folder. Merging is done by Gradle not by AndroidStudion (it only run consequence of commands like "gradle assembleDebeg" or you can do it manyally by "./gradlew assembleDebug") – vitalii Nov 27 '15 at 09:55
0

It's not possible to merge manifests with different package names.
I think this is the problem.
Just remove package="com.myflavour.app" from myflavour manifest.

Stas Parshin
  • 7,973
  • 3
  • 24
  • 43