Single flavor module based on multi flavor library in Gradle
Asked Answered
W

4

11

I'm working on a multi-flavor app. (gradle files below)

It uses a library called tracker that follow the same flavors internal and external

Now for the tricky part, come a new module called feature, this one has no flavor but it needs the tracker as dependency

app.gradle:

android {

    buildTypes {
        debug {
        }
        release {
        }
    }

    flavorDimensions "target"

    productFlavors {
        internal {
            dimension "target"
        }

        external {
            dimension "target"
        }
    }
}

tracker.gradle:

android {

    publishNonDefault true

    buildTypes {
        release {
        }
        debug {
        }
    }

    flavorDimensions 'target'

     productFlavors {
        internal {
            dimension "target"
        }

        external {
            dimension "target"
        }
    }
}

feature.gradle:

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    defaultConfig {
        compileSdkVersion rootProject.ext.compileSdkVersion
        buildToolsVersion rootProject.ext.buildToolsVersion

        defaultConfig {
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            versionCode 1
            versionName "1.0"
            javaCompileOptions {
                annotationProcessorOptions {
                    includeCompileClasspath false
                }
            }
        }
    }

}

dependencies {
    implementation(
            [...]
            project(':tracker')
    )
}

Here are the errors when I try to gradle sync:

Unable to resolve dependency for ':feature@debug/compileClasspath': Could not resolve project :tracker.

Could not resolve project :tracker.
Required by:
    project :feature
 > Project :feature declares a dependency from configuration 'implementation' to configuration 'externalRelease' which is not declared in the descriptor for project :tracker.

Unable to resolve dependency for ':feature@debugAndroidTest/compileClasspath': Could not resolve project :tracker.

Could not resolve project :tracker.
[...]
Wiring answered 27/12, 2017 at 9:50 Comment(3)
try this: implementation project(path: ':tracker', configuration: 'externalRelease')Percuss
> Project :feature declares a dependency from configuration 'implementation' to configuration 'externalRelease' which is not declared in the descriptor for project :tracker.Wiring
read this blog medium.com/mindorks/…Brilliancy
G
6

My gradle version is 4.4.

In doc, Android developer and Android Plugin DSL Reference show that, should add follow code.

missingDimensionStrategy 'external'
missingDimensionStrategy 'target'

Android developer link image

Android Plugin DSL Reference image

but it not work for me. Finally I add follow code in feature.gradle.

flavorDimensions 'target'

 productFlavors {
    internal {
        dimension "target"
    }
}
Grishilda answered 20/9, 2018 at 7:9 Comment(2)
This does not sound like an answer, or?Myles
The doc show missingDimensionStrategy is the answer. Maybe it can help someone who in different gradle version.Circumambient
K
2

From your question, what I get is that you trying to add the library tracker to your feature module as dependency. In your feature.gradle try the following:

dependencies {
    implementation project(':tracker')
}

With Gradle 3.0, there are two new keywords implementation and api. compile keyword is deprecated. You can use implementation as default. Use api especially when you have a transitive dependencies in your project (Module -> Lib1 -> Lib2), and you need to tell Gradle that the module wants to transitively export that dependency to other modules, so that it's available to them at both runtime and compile time.

Good pictorial explanation:

Here is a good article telling difference between the implementation and api keyword: Implementation Vs Api in Android Gradle plugin 3.0

Official doc explanation:

Here is a brief explanation from the official documentation Use the new dependency configurations:

  • Implementation:

    When your module configures an implementation dependency, it's letting Gradle know that the module does not want to leak the dependency to other modules at compile time. That is, the dependency is available to other modules only at runtime. Using this dependency configuration instead of api or compile can result in significant build time improvements because it reduces the amount of projects that the build system needs to recompile. For example, if an implementation dependency changes its API, Gradle recompiles only that dependency and the modules that directly depend on it. Most app and test modules should use this configuration.

  • api:

    When a module includes an api dependency, it's letting Gradle know that the module wants to transitively export that dependency to other modules, so that it's available to them at both runtime and compile time. This configuration behaves just like compile (which is now deprecated), and you should typically use this only in library modules. That's because, if an api dependency changes its external API, Gradle recompiles all modules that have access to that dependency at compile time. So, having a large number of api dependencies can significantly increase build times. Unless you want to expose a dependency's API to a separate test module, app modules should instead use implementation dependencies.

Hope this helps.


Update

For completeness sake, it seems there is a known issue with with gradle 4.1. Using version 4.3 helps. Thanks to Damien.

Khalil answered 2/1, 2018 at 10:27 Comment(4)
changing to api, this is what's happening now: Unable to resolve dependency for ':feature@debug/compileClasspath': Could not resolve project :tracker. Could not resolve project :tracker. Required by: project :feature > Cannot choose between the following configurations of project :tracker: - externalDebugApiElements - internalDebugApiElements All of them match the consumer attributes:Wiring
There is a known issue with gradle 4.1, you will be correct with version 4.3Wiring
Aah! I see. Glad you were able to figure out the issue.Khalil
@DamienLocque Is there any link where I can read more about this issue with gradle 4.1?Khalil
W
0

Ok thanks to @ramin-eftekhari I managed to make it work

https://github.com/luxsypher/gradle-flavor-dependency

Wiring answered 4/1, 2018 at 14:27 Comment(1)
Your sample doesn't work actually. If you put some classes into :tracker and :feature modules, then :feature module doesn't see classes from :tracker module(Myrica
H
-1

Try to add this in app build.gradle defaultConfig block:

missingDimensionStrategy "internal"
Hexavalent answered 4/1, 2018 at 14:40 Comment(2)
I get an error : List of requested values cannot be emptySverdlovsk
Use the following snippet in the debug and release configuration of your app's build.gradle ` debug{ matchingFallbacks = ['release', 'debug'] } release{ matchingFallbacks = ['release', 'debug'] } `Manhour

© 2022 - 2024 — McMap. All rights reserved.