Maintaining different build flavors across modules in Android Studio - android

So I am trying to architect my project based on a MVP pattern for Android. I have used this excellent article as my base. While it works great, I was wondering how would I be able to maintain different build flavors(Staging & Production) across modules.
More details -
I have a module named common which contains a Constants.java file which has URL's and other base settings/constants. What I want to be able to do is have different Constants.java file for staging and production. In the same module, it is easily done, but since my common module is separate from my main app module, I am not sure how would I achieve this.
Any pointers would be appreciated. Thanks

Though I haven't done this myself yet, according to the documentation, you can have different flavors for your library module and reference them from a flavored app module as follows:
//:app build.gradle
productFlavors {
stage {
}
prod {
}
}
dependencies {
stageCompile project(path: ':common', configuration: 'stageRelease')
prodCompile project(path: ':common', configuration: 'prodRelease')
}
//:common build.gradle
android {
publishNonDefault true
}
productFlavors {
stage {
}
prod {
}
}

Related

Adding dependency on app with product flavors

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.

Android Gradle compile project's specific flavor

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"
}
}

Android Multiple Flavors with Multiple Build Types

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.

Conditional dependencies with Gradle, is it possible?

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.

Android Studio Build Variants

I'm dealing with a project that has a large number of dependencies. This has become a problem because when adding new SDK's we're going past the maximum limit of methods that an APK can hold (65536).
I'm looking at using the new build system in Android Studio in order to create build variants that rely on subsets of our dependencies. I was able to find a number of tutorials that help with creating different class alternatives using build flavours, but I didn't find anything regarding specifying different dependencies for each flavour. Is this even possible? What would the whole workflow look like?
For example, I would like to create a build variant that removes Flurry support. I would be able to create a different class that does not instantiate the Flurry SDK, but I would also like to be able to remove the lib dependency entirely, in order to reduce the total number of methods in the APK.
I'm also open to any suggestion regarding managing this kind of issue :)
This works (making sure dependencies are listed after productFlavors):
android {
...
productFlavors {
flavor1 { ...
...
dependencies {
flavor1Compile ...
}
But this won't work:
android {
...
dependencies {
flavor1Compile ...
}
...
productFlavors {
flavor1 { ...
...

Categories

Resources