0

I have a project that uses ~30 product flavors. Apart from the "main" code, the flavors don't have much to them, just some unique resources. Since there are so many, I would like to structure my code directories like this to make it more organized:

  • src
    • main
      • java
      • res
    • productFlavors
      • flavor1
        • java
        • res

But the build doesn't recognize the flavors when they are on a different level than the "main" folder. Is there any way I can make this work?

KairisCharm
  • 1,363
  • 1
  • 13
  • 32

1 Answers1

5

I have a project that uses ~30 product flavors

One more, and you'll match Baskin-Robbins' original ~31 flavors.

But the build doesn't recognize the flavors when they are on a different level than the "main" folder. Is there any way I can make this work?

You can override where source comes from in your module's build.gradle file. While I haven't tried it for your scenario (only for building Eclipse-style projects using Gradle), something like this should work:

android {
    // lots of cool stuff here

    sourceSets {
        flavor1 {
            manifest.srcFile 'src/productFlavors/flavor1/AndroidManifest.xml'
            java.srcDirs = ['src/productFlavors/flavor1/java']
            aidl.srcDirs = ['src/productFlavors/flavor1/aidl']
            res.srcDirs = ['src/productFlavors/flavor1/res']
            assets.srcDirs = ['src/productFlavors/flavor1/assets']
        }

        // lather, rinse, repeat
    }
}

If you stick to the fixed pattern of src/productFlavors/.../ (where ... is the flavor name), you can probably use a bit of Groovy scripting to iterate over an array of flavor names and wire up the sourcesets accordingly.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Well, I would try that, except I get Error:(19, 0) Could not find property 'manifest' on source set 'flavor1'. I get that for everything except the 'java' property – KairisCharm Nov 30 '15 at 19:22
  • Ok, I changed res.srcDirs to resources.srcDirs, and that works, but I do need something for the manifest. – KairisCharm Nov 30 '15 at 19:27
  • @KairisCharm: That's strange. I just added the `sourceSets` closure shown above, after a `productFlavors` closure to define `flavor1`, and I don't get any build errors. `resources.srcDirs` would be for Java resources, not Android ones. It feels like you aren't building this in an `android` project. – CommonsWare Nov 30 '15 at 19:28
  • @KairisCharm: FWIW, http://pastebin.com/8UX8Z8w4 contains the `app/build.gradle` that I tried. It's mostly just a stock app from the new-project wizard, with one change (I was testing something with my `cwac-security` library) beyond the aforementioned stuff. I don't even have those directories and I don't get a build error when I run `gradle assembleFlavor1Debug`. – CommonsWare Nov 30 '15 at 19:35
  • You called it. As it turns out, the sourceSets folder was not under the "android" closure. Not certain why the old developer had it that way... – KairisCharm Nov 30 '15 at 20:02
  • Hey, coming back to this, I thought I had this working ok, but as it turns out, it's not quite right. Each flavor has its own manifest file, but there is also a master manifest file in main that all of the flavors share. My permissions that are listed in that master manifest are no longer working. – KairisCharm Dec 08 '15 at 22:56
  • @KairisCharm: That "master manifest" should be the one in your `main` sourceset. – CommonsWare Dec 08 '15 at 22:57
  • It is... didn't I say that? – KairisCharm Dec 09 '15 at 13:50
  • 1
    @KairisCharm: Sorry, missed that. Check your generated manifest, post-merger, and the manifest merger reports. Both are in `build/` of your module (e.g., `app/`, or whatever module these sourcesets are in). If the permissions are in the merged manifest, your problem lies elsewhere (e.g., Android 6.0 runtime permissions). If the permissions are not in the merged manifest, the merger report may give you clues as to why they're being excluded. – CommonsWare Dec 09 '15 at 14:36
  • They are in the merger report, but not in the generated manifest – KairisCharm Dec 09 '15 at 15:13
  • @KairisCharm: The merger report should be indicating that they are being blocked or something, assuming the merger report is for the build variant whose merged manifest is the one that you are examining. I suggest that you ask a separate Stack Overflow question, where you provide relevant snippets from the original manifests (`main` and a flavor), the equivalent snippets from the merged manifest, and the manifest merger report. – CommonsWare Dec 09 '15 at 15:15
  • I was looking in the wrong place. The merged manifest is complete, however, several errors shown in the merged version saying "Attribute android:{xxx} is not allowed here." – KairisCharm Dec 09 '15 at 15:44
  • Oh, also, under "xmlns:android="http://schemas.android.com/apk/res/android"" the uri is in red, saying "URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)" – KairisCharm Dec 09 '15 at 15:52
  • @KairisCharm: Well, since your app builds, whatever errors you are seeing there presumably are IDE issues. What are the permissions that concern you? What is the merged manifest's `targetSdkVersion`? And what version of Android are you testing on? – CommonsWare Dec 09 '15 at 15:54
  • Right now it is crashing on android.permission.ACCESS_COARSE_LOCATION. targetSdk is 23, and my emulator is 23. – KairisCharm Dec 09 '15 at 15:56
  • 1
    @KairisCharm: Then you probably have not implemented Android 6.0 runtime permissions, as `ACCESS_COARSE_LOCATION` is `dangerous`, so you no longer get it automatically. Either drop your `targetSdkVersion` to 22 (or lower), or add runtime permission support. – CommonsWare Dec 09 '15 at 15:57
  • I did not realize that was a requirement now. Thanks a lot. You're always a big help with all my Android problems, @CommonsWare. – KairisCharm Dec 09 '15 at 19:04
  • you always help me a lot. I was hoping you could provide some input into this: http://stackoverflow.com/questions/37760401/firebase-anr-not-even-using-firebase – KairisCharm Jun 11 '16 at 15:22