I have a library project with 2 flavors
configurations {
// Initializes placeholder configurations that the Android plugin can use when targeting
// the corresponding variant of the app.
internalDebug {}
internalRelease {}
externalDebug {}
externalRelease {}
}
flavorDimensions("outerInner")
productFlavors {
internal{dimension "outerInner"}
external{dimension "outerInner"}
}
No custom sourceSets defined in build.gradle
For one of the flavor I have custom layouts inside:
All other sources should be from main.
When I include this libaryr to app:
implementation project(path: ':sdk', configuration: 'internalDebug')
There no classes of the sdk library at all and all imports marks as red.
The question is why there is no sources from main's library folders in app?
Finally I got the solution as defining missingDimensionStrategy in app's build.gradle.
// Specifies a sorted list of flavors that the plugin should try to use from
// a given dimension. The following tells the plugin that, when encountering
// a dependency that includes a "minApi" dimension, it should select the
// "minApi18" flavor. You can include additional flavor names to provide a
// sorted list of fallbacks for the dimension.
missingDimensionStrategy 'outerInner', 'internal'
It means that if during the build gradle will found a dependency that have the flavorDimension outerInner it should use internal for that.
After this is applied I could simply include
implementation project(path: ':sdk')
For each app's buildType it will use appropriate debug or relese SDK build and fallback to internal implementation.
External implementation is delivered to maven with artifact bundleExternalDebugAar setting.
Related
I'm trying out the Android's latest app packaging and delivery model, App Bundles.
I've created a dynamic feature module and defined a dependency on the main app.
implementation(':app')
Now my app module has different productFlavors.
productFlavors {
free {
...
}
pro {
...
}
}
My dynamic feature does not require any product flavors. But I now get the following error on gradle sync -
Unable to resolve dependency for ':dynamic_feature#debug/compileClasspath':
Could not resolve project :app.
I can fix this by defining the same productFlavors in my dynamic feature module, but is it absolutely necessary?
I am generalizing a case where I have many different submodules and productFlavors and defining productFlavors in each module feels redundant.
In this case you'll have to declare a missingDimensionStrategy for the dynamic feature module which doesn't have the flavor.
In your com.android.dynamic-feature module you'd add something like this
android {
// other things
defaultConfig {
// other things
missingDimensionStrategy 'pro' // or whichever dimension you want to use
}
}
You can find more about this and why this is necessary in the documentation.
I am having troubles with product flavors, my project contains library named Core and application named i.e. App.
In build.gradle file of my App module I am compiling this library project like this:
dependencies {
compile project(':Core')
}
This is working fine but issue comes when I want to introduce specific product flavors in both my library project "Core" and my application module "App".
In Core buid.gradle file I have defined one product flavor :
productFlavors {
flavor1 {
}
}
sourceSets.flavor1 {
java {
exclude '**/SomeFilePath/*'
}
}
Now once I've added this new flavor to my Core library, I want to change build.gradle in my App application module so that I can compile only this productFlavor named flavor1 from my Core project.
I tried something like this, but it fails with error "No configuration with named "flavor1Release" found."
dependencies {
compile project(path: ':Core', configuration: 'flavor1Release')
}
Just to sum it all, I want to have multiple flavors in my App application module and each of this flavors would compile different flavor from my Core library project. This way every flavor from my App module would have different files included in build from this Core library.
Does anyone know how can I accomplish this?
As I can see you are explicitly providing the configuration to compile your project. But you don't need to do that because "Android Studio" already provide that option
To work on files from a particular flavor, click on Build Variants on
the left of the IDE window and select the flavor you want to modify in
the Build Variants panel,
For product flavors you need to specify following things:
productFlavors {
demo {
applicationId "com.buildsystemexample.app.demo"
versionName "1.0-demo"
}
full {
applicationId "com.buildsystemexample.app.full"
versionName "1.0-full"
}
}
We have a project with multiple flavors and each flavor has 3 different buildTypes: debug, QA and release.
productFlavors {
flavor1 {}
flavor2 {}
flavor3 {}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
qa {
applicationIdSuffix ".qa"
}
release {
..
}
But for each flavor and buildType we need different library dependency. For example:
compile 'baseUrl:myLibrary:1.0.0:flavor1Release#aar'
compile 'baseUrl:myLibrary:1.0.0:flavor1Qa#aar'
...
compile 'baseUrl:myLibrary:1.0.0:flavor3Qa#aar'
Can we add these dependencies using a Groovy script?
I know that you can define specific dependency per buildType like this
debugCompile 'baseUrl:myLibrary:1.0.0:debugLib#aar'
releaseCompile 'baseUrl:myLibrary:1.0.0:release:Lib#aar'
compile: main application
androidTestCompile: test application
debugCompile: debug Build Type
releaseCompile: release Build Type.
Because it’s not possible to build an APK that does not have an
associated Build Type, the APK is always configured with two (or more)
configurations: compile and Compile. Creating a new Build
Type automatically creates a new configuration based on its name.
It also seems to be working just fine with flavor as described here (but not with flavorDimensions)
Doing it for a variant (buildType+Flavor) seems a bit more work. Otherwise you could define your library as a real library project and use a syntax like this
To create a dependency on another published artifact, you need to
specify which one to use:
dependencies {
flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}
From: http://tools.android.com/tech-docs/new-build-system/user-guide
Solution
If you want to create multiple build type in our single project.So you need follow this https://stackoverflow.com/a/66315794/12134511 I am use following code working is fine so don't go anywhere just follow link.
I hope this code help full for you.
I have a main Android project, which depends on a submodule.
The main project has flavors defined in Gradle.
Also the submodule has a few flavors defined. This should be logical - to be able to have flavors for both projects.
For example in the submodule:
productFlavors {
flavorName {
}
}
But this does not work - The build crashes with a message saying that submodule resources are not found in the main project.
But when I delete flavors from the submodule, everything works fine.
It seems to mix the build order when flavors are defined for the subproject, could this be true?
What am I missing? Is it even possible for both main and sub projects to have flavors?
When you reference your sub-modules as dependencies in your build.gradle file, be sure to specify which flavor of the sub-module you are referring to:
dependencies {
compile project(path: ':module', configuration:'yourflavorDebug')
}
then be sure in your build variants, you are building the flavor your main module depends on, and everything should work out.
Also be sure the libraries you are referencing have this in their build.gradle as well:
publishNonDefault true
Without it android studio doesn't seem to be able to depend on flavors of that module. More information here.
I have an Android project (already ported to Android Studio and using Gradle) that is made up of different modules.
The project is actually used to create two different apps, where the code is pretty much the same, except for some resources.
Thus the resources have been split into two different modules.
The original author of this project used to work in Eclipse and switch the resource modules included in the dependencies based on which app he wanted to build. And he also used to change by hand the package name in AndroidManifest.xml
I would like to automate all of this and still have a single code base, but have two build targets with specific modules for each target. Is that doable with Gradle?
Update:
To make things even harder, my project has a hierarchy that is pretty much the following:
--+--MainProject
+--LibData
+--LibBase
+--LibResA
+--LibResB
Where:
MainProject depends on LibBase and LibData.
LibData depends on LibBase
LibBase either depends on LibResA or LibResB based on the final APK that I need to build.
As suggested, I've tried implementing this with flavors by adding in the MainProject build.gradle the following:
productFlavors {
producta {
}
productb {
}
}
And then in LibBase I've added the following to its build.gradle:
dependencies {
productaCompile project(':LibResA')
productbCompile project(':LibResB')
}
But then, when I build the project, LibData can't find the classes and resources inherited from LibBase. So now I'm stuck with this error. To me it looks like LibBase isn't being copied to the intermediates of LibData. That way LibData can't resolve the classes in LibBase, but it's just my assumption.
Update 2:
I kept investigating this issue and now I've changed my build.gradle files to look like this:
Main Project build.gradle:
defaultPublishConfig "productaRelease"
publishNonDefault true
productFlavors {
producta {
applicationId "com.producta"
}
productb {
applicationId "com.productb"
}
}
dependencies {
compile project(':LibData')
}
LibData build.gradle (has no product flavors, just the dependencies):
dependencies {
compile project(':LibBase')
}
LibBase build.gradle:
defaultPublishConfig "productaRelease"
publishNonDefault true
productFlavors {
producta {
}
productb {
}
}
dependencies {
productaCompile project(path: ':LibResA')
productbCompile project(path: ':LibResB')
}
This way I get no errors when doing the usual gradle clean build but I can see that the resources included are always those of LibResA just like the defaultPublishConfig is the only one used at all times.
If I open this project in Android Studio (0.8.1 atm) the result is that if I try to switch the build variant of the LibBase module and set it to productbRelease, the following error is being shown: Error:Module 'LibBase' has variant 'productbRelease' selected, but the module ''LibData'' depends on variant 'productaRelease'.
I'm running out of ideas.
Since you already have the product flavors:
productFlavors {
producta {
}
productb {
}
}
Define your dependencies prefixed with flavor name.
Example:
dependencies {
productaImplementation 'com.google.android.gms:play-services:11.0.2'
productbImplementation 'com.google.android.gms:play-services:12.0.1'
}
Common dependencies will be defined normally.
Now build apk for individual flavors.
Not the best way to do it, but if productFlavors is not enough to specify conditional dependencies you can rely on an inline if and evaluate it based on some value that can be injected via external properties.
For example here is how I toggle LeakCanary (no-op is just the empty implementation of the other one):
build.gradle
dependencies {
compile "com.squareup.leakcanary:leakcanary-android"+(project.ext.has("leakCanary")?"":"-no-op")+":1.3.1"
}
To build with com.squareup.leakcanary:leakcanary-android:1.3.1:
$ ./gradlew :app:assembleDebug -PleakCanary
By default it builds with the empty implementation com.squareup.leakcanary:leakcanary-android-no-op:1.3.1:
$ ./gradlew :app:assembleDebug
This provides a quick and more flexible way to toggle things using build command, but too much of it and things will get messy real quick.
Yes, it is. New Android build system based on Gradle supports your use case with its concept of product flavors. http://tools.android.com/tech-docs/new-build-system/user-guide
Note that you will likely want to switch from Eclipse to Android Studio when you do migration to Gradle build.