I have a project with two flavors dimensions. One is endpoint and it is used for switching prod/staging. Other is site and it is for different color schemes and data sources. There are about 20 site flavors and only two endpoints. So, flavors configuration looks like this:
flavorDimensions "site", "endpoint"
productFlavors {
pro {
dimension 'endpoint'
}
staging {
dimension 'endpoint'
}
site1 {
dimension 'site'
applicationId "co.site1"
}
…
site20 {
dimension 'site'
applicationId "co.site20"
}
}
Now I need to move API requests to separate module. So, it'll be fine to move endpoints configuration to this module. So, app flavors should be:
In app:
productFlavors {
site1 {
applicationId "co.site1"
}
…
site20 {
applicationId "co.site20"
}
}
In API library:
productFlavors {
pro {
}
staging {
}
}
But how to combine them? Earlier I could easily get builds like App-proSite15. How to configure the same with two modules?
Currently my solution is to leave configuration as is. I have only string resources in endpoint flavors, and can access them in API module by string name via getIdentifier
Related
In my application i have different productFlavors(DEV, DEMO,PROD) and each productFlavors has debug and release modes.
As i need to use different values for remote config, i have created 2 projects, one for Prod, another one QA. Now i have 2 different google services.json file.
I tried to keep json file in my app and run app, but app is always expecting json file in app folder and if keep one in app folder and another one at flavor folder is is not picking flavor json and always taking app json file.
buildTypes {
release {
}
debug {
}
}
// Specifies one flavor dimension.
flavorDimensions "client", "server"
productFlavors {
Customer1 {
dimension "client"
}
Customer2 {
dimension "client"
}
DEV {
dimension "server"
applicationIdSuffix ".dev"
}
DEMO {
dimension "server"
applicationIdSuffix ".demo"
}
PROD {
dimension "server"
}
QA {
dimension "server"
applicationIdSuffix ".qa"
}
}
Any help on this?
Here is a problem, for example, I need the next three dimensions for my app: "brand", "environment", "market". The configuration will look like this:
flavorDimensions "brand", "environment", "market"
productFlavors {
// brand
nike{
dimension "brand"
applicationId "com.android.nike"
}
adidas{
dimension "brand"
applicationId "com.android.adidas"
}
// environment
test{
dimension "environment"
applicationIdSuffix ".test"
}
prod {
dimension "environment"
}
// market
google {
dimension "market"
}
amazon {
dimension "market"
}
}
As a result, I can build the next 8 applications (I ignoring build types in this example):
nikeTestGoogle
nikeTestAmazon
nikeProdGoogle
nikeProdAmazon
adidasTestGoogle
adidasTestAmazon
adidasProdGoogle
adidasProdAmazon
As I understand documentation about flavor dimensions (https://developer.android.com/studio/build/build-variants#flavor-dimensions), application nikeTestGoogle use files from the next folders: main, nike, test, google, nikeTest, nikeTestGoogle. But it doesn't work, Android studio sees only files in main, nike, test, google, and nikeTestGoogle. Files in nikeTest ignored and even doesn't mark as currently active.
Does anyone know why it happened?
Small example will describe the case:
flavorDimensions 'shape', 'api'
productFlavors {
fruit {
dimension "shape"
}
vegtable {
dimension "shape"
}
production {
dimension "api"
}
development {
dimension "api"
}
}
Task:
I need to keep different signing config for fruitProduction and fruitDevelopment flavors.
I have researched the gradle doc and I have not found the suitable task where I can override the config for special flavor.
I have two flavors in my Android project, one works with test server and one with production. I store the URL inside a string resource, so I may access the correct URL based on a flavor that I choose for compilation. Usually I need to create multiple apk files during a day, each time for both servers.
Is there a way to create two apk files each time I run my project or build an apk from Build menu?
If you have something like this:
android {
productFlavors {
dev {
applicationId "your.com.android.devel"
buildConfigField 'String', 'HOST', '"http://192.168.1.78"'
}
prod {
applicationId "your.com.android"
buildConfigField 'String', 'HOST', '"http://yourserver.com"'
}
}
}
You only have to run assemble in Gradle projects
And you can find all the different apks build/outputs/apk
Hope this time I'd be more helpful
Mastering "Product Flavors" on Android
The only thing you have to do is to define it on each of your product flavors:
android {
productFlavors {
devel {
applicationId "zuul.com.android.devel"
}
prod {
applicationId "zuul.com.android"
}
}
}
Send requests to multiple hosts depending on the flavor
As before, you must include some params on your product flavor config field.
android {
productFlavors {
devel {
applicationId "zuul.com.android.devel"
buildConfigField 'String', 'HOST', '"http://192.168.1.34:3000"'
}
prod {
applicationId "zuul.com.android"
buildConfigField 'String', 'HOST', '"http://api.zuul.com"'
}
}
}
As an example, we will try to show you how you can integrate this with Retrofit to send request to the appropiate server without handling which server you're pointing and based on the flavor. In this case this is an excerpt of the Zuul android app:
public class RetrofitModule {
public ZuulService getRestAdapter() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(BuildConfig.HOST)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
return restAdapter.create(ZuulService.class);
}
}
As you can see you just have to use the BuildConfigclass to access the variable you've just defined.
You can use this command line in Gradle:
./gradlew assemble
Or you can generate saparately all flavors for debug or release respectively
./gradlew assembleDebug
./gradlew assembleRelase
How is it possible to identify the current flavor being compiled. I'm trying to add a file to compile only if I'm compiling a certain product flavor.
buildTypes {
android.applicationVariants.all { variant ->
variant.productFlavors.each() { flavor ->
if (flavor.name.equals(currentFlavorName)) {
The problem is that I can't seem to find where the currentFlavourName of the flavor which I am currently building is located.
just put the strings you want for flavor1 into:
src/flavor1/res/values/strings.xml
and the strings for flavor2 into:
src/flavor2/res/values/strings.xml
no need to put logic into your gradle file
Android uses a unique build process regarding your resources for different flavors and it is very easy to control.
if you set up your main source:
project-name
------------/app
---------------/src
-------------------/main
------------------------/res
----------------------------/values
------------------------/java
-------------------/development
-------------------------------/res
-----------------------------------/values
-------------------------------/java
-------------------/production
------------------------------/res
----------------------------------/values
------------------------------/java
This would be a bottom up approach from product flavor into main. Meaning if you have a strings.xml with items having the same name existing in development/res/values and have values that also exist in main/res/values/strings.xml these will be over written (and same would go for the production flavor) based on the build variant defined in your gradle file.
android {
productFlavors {
production {
applicationId "com.test.prod"
versionName "1.0.0"
}
development {
applicationId "com.test.dev"
versionName "1.0.0"
}
}
I don't know if exits a method to get the currentFlavor. I haven't found it yet.
A ugly solution can be
variant.productFlavors.each() { flavor ->
if (flavor.name.equals("flavor1")) {
//..........
}
}
However, if you want to be able to control which strings.xml you are using, you can achieve it in different ways.
First of all you can just define a xml file in your flavor folder.
app/src/main/res/values/ -> for common resources
app/src/flavor1/res/values -> resources for flavor1
app/src/flavor2/res/values -> resources for flavor2
This doesn't require any config in your build.gradle script.
A second option is to define a resource value using build.gradle.
Something like:
productFlavors {
flavor1 {
resValue "string", "app_name", "IRCEnterprise"
}
//....
}
Another option is to create some field in your BuildConfig class using this kind of script.
productFlavors {
flavor1 {
buildConfigField "String", "name", "\"MY FLAVOR NAME\""
}
}