Android flavors, Gradle sourceSets merging - android

I try to make an application for multiple partners and for each partner a test and prod version. For each flavors I create a specific folder with res/values in it like the documentation said.
My gradle file look like this :
apply plugin: 'com.android.application'
android {
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
}
compileSdkVersion 14
buildToolsVersion "21.1.2"
defaultConfig {
versionCode 1
versionName 1
minSdkVersion 14
targetSdkVersion 19
}
productFlavors {
prodPARTNER1 {
applicationId "com.PARTNER1"
}
testPARTNER1 {
applicationId "com.PARTNER1.test"
}
prodPARTNER2{
applicationId "com.PARTNER2"
}
testPARTNER2{
applicationId "com.PARTNER2.test"
}
}
sourceSets {
testPARTNER2 {
res.srcDirs = ["testPARTNER2/res", "prodPARTNER2/res"]
}
}
}
dependencies {
compile project(':ViewPagerIndicatorLibrary')
compile 'com.android.support:support-v4:19.0.0'
compile 'com.google.android.gms:play-services:+'
compile files('libs/achartengine-1.1.0.jar')
compile files('libs/android-async-http-1.4.4.jar')
compile files('libs/jackson-annotations-2.2.3.jar')
compile files('libs/jackson-core-2.2.3.jar')
compile files('libs/jackson-databind-2.2.3.jar')
compile files('libs/urlimageviewhelper-1.0.4.jar')
}
I want for a test version to take res folder of the prod version (like this I not duplicate resources for both version) and merge it with the test version.
The problem is :
Error:Error: Duplicate resources:
C:\...prodPARTNER2\res\values\strings.xml:string/app_name, C:\...testPARTNER2\res\values\strings.xml:string/app_name
Any idea ? It's not possible to merge too res folder for the same flavors ?
EDIT : I use gradle v 1.1.0 and android studio v 1.1.0 too

Warning: this approach has changed a little bit on Android Plugin for Gradle 3.0.0
Use productFlavors for each partner app and define a build type test for test builds.
productFlavors {
partner1 {
applicationId "com.partner1"
}
partnerN {
applicationId "com.partnerN"
}
}
buildTypes {
debug {
// use defaults
}
release {
// the 'prod' version, use defaults
}
test {
// config as you want!
applicationIdSuffix ".test"
versionNameSuffix " Test"
debuggable true
minifyEnabled false
signingConfig signingConfigs.debug
}
}
You can use mix and match source folders as the Android Plug-in for Gradle shows:
To build each version of your app, the build system combines source code and resources from:
src/main/ - the main source directory (the default configuration common to all variants)
src/<buildType>/ - the source directory
src/<productFlavor>/ - the source directory
Edit: This user guide is another source of help: http://tools.android.com/tech-docs/new-build-system/user-guide
Edit 2: according to the link above:
Additional sourcesets are also created for each variants:
android.sourceSets.flavor1Debug
Location src/flavor1Debug/
android.sourceSets.flavor1Release
Location src/flavor1Release/
android.sourceSets.flavor2Debug
Location src/flavor2Debug/
android.sourceSets.flavor2Release
Location src/flavor2Release/
Then, you can use /src/partner1Test/ to define resources specifics to partner1 flavor AND Test build, that is a partner1Test build variant.

Related

Cannot filter assets for multiple densities using SDK build tools 21 or later

Due to an issue building my application in release mode with the gradle plugin 1.3.0, I have switched to 1.4.0 (beta 2), which fixes said build issue.
However, whereas some flavors build perfectly, others have their build aborted with the following error message:
Cannot filter assets for multiple densities using SDK build tools 21 or later. Consider using apk splits instead.
I haven't found any reference to the sentence above, what should I do with the resources of these flavors, or even why this error only appears in a couple of flavors and not in all of them.
Edit: build.gradle
apply plugin: 'com.android.application'
android {
signingConfigs {
config {
}
}
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.appname"
minSdkVersion 8
targetSdkVersion 23
versionCode 1
versionName '0.0.1'
}
buildTypes {
release {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
minifyEnabled true
zipAlignEnabled true
signingConfig signingConfigs.config
}
debug {
applicationIdSuffix 'debug'
versionNameSuffix '_debug'
}
}
flavorDimensions "googleplay"
productFlavors {
noplay {
dimension "googleplay"
versionCode Integer.parseInt(defaultConfig.versionCode + "0")
buildConfigField "boolean", "HAS_GOOGLE_PLAY", "false"
resConfigs "ldpi", "mdpi"
// so far we are using the noplay flavor only for old devices, which do not have hidpi
}
play {
dimension "googleplay"
versionCode Integer.parseInt(defaultConfig.versionCode + "1")
buildConfigField "boolean", "HAS_GOOGLE_PLAY", "true"
minSdkVersion 9
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
// Google Play services (analytics)
playCompile 'com.google.android.gms:play-services-analytics:8.1.0'
// ActionBar and support libraries
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:support-v4:23.0.1'
}
resConfigs is replaced by APK splits for densities and architectures. Note the following sentence:
When using build tools older than 21 you could also add resConfigs
"nodpi", "hdpi" to also limit the density folders that are packaged.
Instead, use apk splits to provide different apks to devices with
different densities.
There is a bug report for this issue.
The offending resConfigs have to be removed, and apk splits can be used in their instead.
Alternatively, switching to build-tool 20.0.0 seems work around this problem.

Android Studio buildflavors

Getting started with the new android studio it seems very flexible but that usually brings a steep learning curve. Hoping to get some help with that here.
I've built an app and deployed it with this build.gradle file
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "23.0.0"
defaultConfig {
applicationId "me.test.simpleProject
minSdkVersion 10
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
signingConfigs {
release {
storeFile file("../my.keystore.jks")
storePassword System.getenv("and_ks_pw")
keyAlias System.getenv("and_ky_alias")
keyPassword System.getenv("and_k_pw")
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
debuggable true
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.1'
compile project(":Library:lib_my_lib_a")
compile project(":Library:lib_my_lib_b")
compile project(":Library:lib_my_lib_c")
}
This works pretty well and once I learn the syntax it'll be much easier to use than the previous system.
Now my question.
I would like to basically add a few product flavors.
I currently use google analytics to track clicks, usage stats, simple things like that.
In the past [before android studio] typically distribute my apps in a free/ paid version.
I would like to create say build flavors for:
google play free
google play paid
amazon free
amazon paid
The code for these apps should be mostly identical but they cannot be since, for example adding links to google play in your amazon apps gets you in a bit of trouble over there. So I will need to have unique classes across the build flavors.
I was reading some docs and watching google talks about setting up the build flavors but I am a bit confused.
Can someone help me define the folder structure for this project?
current application structure
test/
.gradle/
.idea/
app/
app/build
app/libs <-- empty
app/src
app/.gitignore
app/app.iml
app/build.gradle
app/proguard-rules.pro
build/
gradle/
Library/lib_a
Library/lib_b
Library/lib_c
.gitignore
build.gradle
gradle.properties
gradlew
gradlew.bat
local.properties
settings.gradle
test.iml
Can I place the new folders anywhere and how do I link them up with grade to properly build the variants?
The first thing you should do, is add these flavors to your gradle script, inside the android section:
productFlavors {
googleFree {
applicationId = "com.your.app.gfree"
}
googlePaid {
applicationId = "com.your.app.gpaid"
}
amazonFree {
applicationId = "com.your.app.afree"
}
amazonPaid {
applicationId = "com.your.app.apaid"
}
}
Note that you can define different package names for your app if needed, as well as some additional properties. Full details: Gradle Plugin - Build Variants
At this point you will have three different concepts in your app now:
Build types: Debug and Release
Product flavors: googleFree, googlePaid, amazonFree and amazonPaid
Build variants: Combination of build types and flavors
googleFreeDebug
googleFreeRelease
googlePaidDebug
googlePaidRelease
amazonFreeDebug
amazonFreeRelease
amazonPaidDebug
amazonPaidRelease
Flavor Specific resources:
For defining resources, you should have:
app
src
main
java
res
googlePaid
java
res
googleFree
java
res
amazonPaid
java
res
amazonFree
java
res
With that structure in place, you can place all your shared stuff under main, while the flavor specific stuff would live on each flavor's folder. Then, when building a specific variant of your app, android and gradle will resolve the right resources for you. If you are interested in more details, see Resource Merging.
Once the flavors have been added to your build.gradle file, if you sync your project, Android Studio will be able to pick your build variants and you may select these from the IDE:
To use flavors in your app you should have a structure like this:
app
src
flavor1
java
res
flavor2
java
res
main
java
res
You have to define the flavors in the build.gradle:
productFlavors {
flavor1 {
//
}
flavor2 {
//
}
}
Then you can have different dependencies using:
dependencies {
releaseCompile
debugCompile
flavor1Compile
flavor1DegubCompile
}
For example:
dependencies {
freeCompile 'com.google.android.gms:play-services:7.5.0'
}

Android Studio adds libapp.so to the resulting apk, what is it and how to turn it off?

Android Studio 1.1 generated apk file (located # app/build/outputs/apk folder) contains the lib directory, and for every cpu type there exists a non-empty folder, like /x86. Each of these folder contain a libapp.so shared library that is around 5Kb in size per cpu.
I've searched the net and the only thing I found so far is this link from Intel https://software.intel.com/en-us/articles/building-native-android-apps-using-intelr-c-compiler-in-android-studio that shows how to change the default libapp.so to user-provided library.
So, I guess that this library (libapp.so) is somehow built by gradle.
In fact I do my own native library building, using ndk-build command line tool, and my libs are placed alongside that libapp.so. It's not causing any issues btw, but I feel that I'm losing the control over what is built and why.
Here's my humble build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
/**
* Path to *.so files
*/
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //disable automatic ndk-build
}
}
defaultConfig {
applicationId "com.sample.android"
minSdkVersion 9
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
}
How can I disable this libapp.so being built?
defaultConfig {
ndk {
moduleName "yourSelfLib"
}
}

Adobe Creative SDK integration Android error

Following the given documentation: https://creativesdk.adobe.com/docs/android/#/articles/imageediting/index.html
I proceeded with my project setup but when I go on to edit the build.gradle file for my app and add the compile project(':creativesdk:CreativeSDKImage') dependency and rebuild, the build fails showing the Error:Configuration with name 'default' not found.
Here is my settings.gradle file-
include ':app'
include ':creativesdk'
include ':creativesdk:CreativeSDKImage'
include ':creativesdk:Foundation:CreativeSDKFoundationAuth'
project(':creativesdk').projectDir = new File
("C:\\Users\\Neel Raj\\Desktop\\AdobeTest\\creativesdk-repo\\com\\adobe/creativesdk")
project(':creativesdk:CreativeSDKImage').projectDir = new File
("C:\\Users\\Neel Raj\\Desktop\\AdobeTest\\creativesdk-repo\\com\\adobe/creativesdk/CreativeSDKImage")
project(':creativesdk:Foundation:CreativeSDKFoundationAuth').projectDir = new File
("C:\\Users\\Neel Raj\\Desktop\\AdobeTest\\creativesdk-repo\\com\\adobe/creativesdk/Foundation/CreativeSDKFoundationAuth")
The build.gradle file -
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
applicationId "com.neelraj.adobetest"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.2'
compile project(':creativesdk:CreativeSDKImage')
}
I cannot figure out a way to fix this. I'm not even sure if I'm doing everything correctly. But I have followed the documentation step by step.
Any detailed way to setup the image sdk would be very helpful
I got the same problem with this guide.
Just see here : Trying to make an Android Studio Application with Adobe Creative SDK Image Editing, cannot get libraries compiled in gradle
Follow the steps to configure the SDK.
After that you can follow the rest of the mentioned tutorial.
What helped me was to look at the sample code from Android Creative SDK "CreativeSDKImageSampleApp" and after some hours it worked for me

Android Studio - Build variation & Module selection

I'm building an application which needs a library with 2 variants - simulator & actual.
My objective is to create build tasks say assembleSimulatorDebug & assembleDebug.
assembleSimulatorDebug will include simulator module/library and assembleDebug will include actual module to build the apk.
I'm thinking of having if else blocks in dependencies sections of build.gradle. Can I have something like this?
I'm very new to gradle and trying from yesterday to set up something like this. It will be v helpful if anyone can provide some hints or links where I can get an idea to achieve this.
Update:
Found another solution. It's in another my answer.
It is possible by usage of 'Flavor products' of android gradle plugin. You can split library implementation by product flavor.
Initial requirements 'com.android.tools.build:gradle:1.0.0', Android Studio 1.0.1.
I created project at GitHub, so you'll be able to get it, run and learn.
You need to create two flavors of your app and library, too. For example, normal and simulator
Application's build.gradle
apply plugin: 'com.android.application'
android {
lintOptions {
abortOnError false
}
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
applicationId "com.tivogi.gradle"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
normal {
}
simulator {
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
normalCompile project(path: ':library', configuration: 'normalRelease')
simulatorCompile project(path: ':library', configuration: 'simulatorRelease')
}
Library's build.gradle
apply plugin: 'com.android.library'
android {
publishNonDefault true
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
normal {
}
simulator {
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
Library:
split implementation between flavors by productFlavors (see my sample project if will have questions about that);
add publishNonDefault true into its build.gradle
From Gradle Plugin User Guide
It is also possible to publish all variants of a library. We are planning to allow this while using a normal project-to-project dependency (like shown above), but this is not possible right now due to limitations in Gradle (we are working toward fixing those as well).
Publishing of all variants are not enabled by default.
To enable them:
android {
publishNonDefault true
}
Application:
add normal and simulator product flavors (productFlavors);
add next lines to dependencies section
normalCompile project(path: ':library', configuration: 'normalRelease')
simulatorCompile project(path: ':library', configuration: 'simulatorRelease')
From Gradle Plugin User Guide
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')
}
After all of that you'll be able to build 2 variants of applicaiton: normal and simulator.
Found solution for 2 libraries, it looks simpler. It's based on next from official guide
Finally, like Build Types, Product Flavors can have their own dependencies. For instance, if the flavors are used to generate a ads-based app and a paid app, one of the flavors could have a dependency on an Ads SDK, while the other does not.
dependencies {
flavor1Compile "..."
}
So you can create 2 individual libraries and create 2 flavors, for example, libraries are library-normal and library-simulator and flavors are normal and simulator.
Application build.gradle
apply plugin: 'com.android.application'
android {
lintOptions {
abortOnError false
}
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
applicationId "com.tivogi.gradle"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
normal {
}
simulator {
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
normalCompile project(":library-normal")
simulatorCompile project(":library-simulator")
}
Application:
add only those lines into dependencies;
normalCompile project(":library-normal")
simulatorCompile project(":library-simulator")
Library:
does not require any change;
I published sample project of this solution at individual-libraries branch.

Categories

Resources