Gradle buildtypes override each other - android

I want to set different values for a property depending on which buildType was chosen. But I realized by checking the gradle console that in configuration phase all 3 buildTypes are executed and the value of the last build remains in the property. I think that's not how it should work.
Did I do something wrong?
android {
signingConfigs {
...
}
compileSdkVersion 28
defaultConfig {
...
}
productFlavors {
normal {
manifestPlaceholders = [appName: "#string/app_name"]
signingConfig signingConfigs.configNormalRelease
}
}
buildTypes {
release {
println("app release build")
rootProject.ext.test = false
}
debug {
println("app debug build")
rootProject.ext.test = false
}
staging {
println("app staging build")
rootProject.ext.test = true
}
}
sourceSets {
main {
aidl.srcDirs = ['src/main/aidl']
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
checkReleaseBuilds true
abortOnError false
}
flavorDimensions 'tier'
productFlavors {
normal {
dimension "tier"
}
}
}
Output is
app release build
app debug build
app staging build
value of 'test' property is always true, whether I call assembleRelease, assembleDebug, assembleStaging
Why I see everywhere that people put api keys, urls, and other custom stuff into buildTypes when they get overridden by the last one? I understand that gradle might call all buildtypes during configuration phase, but where to put above mentions values then?

If you want to get your test value from source code in your project, you can set variable:
buildTypes {
release {
buildConfigField 'boolean', 'test', 'false'
}
debug {
buildConfigField 'boolean', 'test', 'false'
}
staging {
buildConfigField 'boolean', 'test', 'true'
}
}
And then you can get this field from your code using BuildConfig class (test field will be generated intoBuildConfig). Get it through BuildConfig.test.
And if you really want to change gradle variable for any buildTypes, you can try to do this:
android.applicationVariants.all { variant ->
boolean isStaging = gradle.startParameter.taskNames.find {it.contains("staging") || it.contains("Staging")} != null
if (isStaging) {
rootProject.ext.test = true
} else {
rootProject.ext.test = false
}
}

Related

minifyWithR8 issue with Dynamic feature module, release build

I am working on a dynamic feature module for the first time. I am getting issues in minify gradle task. It says ListenableFuture file exists in base.jar and alt_acco.jar
below is my project configuration:
mobile.gradle
dynamicFeatures = [':alt_acco']
alt_acco.gradle. feature module
apply plugin: 'com.android.dynamic-feature'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
tasks.lint.enabled = false
}
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
missingDimensionStrategy 'react-native-camera', 'general'
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
incremental true
}
buildTypes {
release {
}
releaseStaging {
matchingFallbacks = ['release']
}
debug {
}
}
productFlavors {
flavorDimensions "type"
standard {
dimension "type"
buildConfigField 'Boolean', 'Automation', 'false'
}
standardBasicOptimized {
dimension "type"
buildConfigField 'Boolean', 'Automation', 'false'
}
standard_charles {
dimension "type"
buildConfigField 'Boolean', 'Automation', 'false'
}
automation_charles {
dimension "type"
buildConfigField 'Boolean', 'Automation', 'true'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dataBinding {
enabled = true
}
}
dependencies {
// Import the Firebase BoM (see: https://firebase.google.com/docs/android/learn-more#bom)
implementation platform('com.google.firebase:firebase-bom:28.2.1')
// Firestore (Java)
implementation 'com.google.firebase:firebase-firestore'
// Firestore (Kotlin)
implementation 'com.google.firebase:firebase-firestore-ktx'
// Google Play services
implementation project(path: ':mobile')
}
settings.gradle
include ':alt_acco'
I am making a release build and the error I am getting is as follows:
Task :mobile:minifyStandardBasicOptimizedReleaseWithR8
/root/.gradle/caches/transforms-3/1169397e4788b932b8c86a71183af227/transformed/jetified-time4j-android-4.2-2018i/proguard.txt:1:1-27: R8: Ignoring option: -useuniqueclassmembernames
/opt/jenkins/workspace/APP-Android-Verify/mobile/build/intermediates/module_and_runtime_deps_classes/standardBasicOptimizedRelease/base.jar: R8: Type com.google.common.util.concurrent.ListenableFuture is defined multiple times: /opt/jenkins/workspace/APP-Android-Verify/mobile/build/intermediates/module_and_runtime_deps_classes/standardBasicOptimizedRelease/base.jar:com/google/common/util/concurrent/ListenableFuture.class, /opt/jenkins/workspace/APP-Android-Verify/alt_acco/build/intermediates/module_and_runtime_deps_classes/standardBasicOptimizedRelease/feature-alt_acco.jar:com/google/common/util/concurrent/ListenableFuture.class
> Task :mobile:minifyStandardBasicOptimizedReleaseWithR8 FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':mobile:minifyStandardBasicOptimizedReleaseWithR8'.
> com.android.tools.r8.CompilationFailedException: Compilation failed to complete, origin: /opt/jenkins/workspace/APP-Android-Verify/mobile/build/intermediates/module_and_runtime_deps_classes/standardBasicOptimizedRelease/base.jar:com/google/common/util/concurrent/ListenableFuture.class
Help will be really appreciated.
Hey I had same issue because we had gradle cache enabled, I got it working by adding ./gradlew bundleRelease --no-build-cache, hope it helps.

How to build several apks at once with custom gradle task?

I'm struggling to find a way for build several apk at once with gradle.
I'd like to have a custom gradle task which considers only variants with enviroment = "production" and all the brands but nonPublishedBrand and buildtype = "release" (see code below).
For each of those variants i need to:
generate the signed apk
upload prodguard mappings to bugsnag with the relative task uploadBugsnag${variant.name}-releaseMapping
rename apk into <brand>-<version>.apk and move it to a common folder $buildDir/myApks
I only found a way to make assemble tasks also run my custom tasks but that's not ideal because i don't want to upload mappings every time a production release variant is built, but only when it's meant i.e. launching a specific gradle task.
Is it possible to achieve that with gradle? Can you please point me in the right direction?
See my build.gradle android section for reference:
android {
compileSdkVersion 27
defaultConfig {
minSdkVersion 15
targetSdkVersion 27
versionCode 1000000
versionName "1.0.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
storeFile file("keystore/keystore")
storePassword '*******'
keyAlias '*******'
keyPassword '*******'
}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
versionNameSuffix ".debug"
manifestPlaceholders = [buildTypePrefix: "D_"]
}
release {
debuggable false
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
manifestPlaceholders = [buildTypePrefix: ""]
}
}
flavorDimensions "environment", "brand"
productFlavors {
//ENVIRONMENTS
staging {
dimension "environment"
applicationIdSuffix ".staging"
versionNameSuffix ".staging"
buildConfigField("String", "BASE_URL", "\"http://baseurl-staging.com\"")
manifestPlaceholders = [environmentPrefix: "S_"]
}
production {
dimension "environment"
buildConfigField("String", "BASE_URL"l, "\"http://baseurl-prod.com\"")
manifestPlaceholders = [environmentPrefix: ""]
}
//BRANDS
nonPublishedBrand {
dimension "brand"
applicationId "${packageBaseName}.nonpublishedbrand"
manifestPlaceholders = [appName: "Non published brand"]
ext {
facebook_app_id = [
staging: "0000000",
prod : "11111111"
]
}
}
brand1 {
dimension "brand"
applicationId "${packageBaseName}.brand1"
manifestPlaceholders = [appName: "Brand 1"]
ext {
facebook_app_id = [
staging: "22222222",
prod : "33333333"
]
}
}
brand2 {
dimension "brand"
applicationId "${packageBaseName}.brand2"
manifestPlaceholders = [appName: "Brand 2"]
ext {
facebook_app_id = [
staging: "44444444",
prod : "555555555"
]
}
}
}
productFlavors {
applicationVariants.all { variant ->
def isDebug = false
if (variant.buildType.name == "debug") {
isDebug = true
}
def isStaging = false
def flavors = variant.productFlavors
def environment = flavors[0]
if (environment.name == "staging") {
isStaging = true
}
def facebookAppId = ""
if (isStaging){
facebookAppId = flavors[1].facebook_app_id.staging
}else{
facebookAppId = flavors[1].facebook_app_id.prod
}
variant.buildConfigField "String", "FACEBOOK_APP_ID", "\"${facebookAppId}\""
}
}
dataBinding {
enabled = true
}
bugsnag {
autoUpload false
}
}
circle.ci is an efficient way to generate builds with each commit. Documentation : https://circleci.com/docs/2.0/
Your circle.yml file would have something like this :
override:
- ./gradlew clean :mobile:assemblePre -PdisablePreDex -Pandroid.threadPoolSize=1 -Dorg.gradle.parallel=false -Dorg.gradle.jvmargs="-Xms2048m -Xmx4608m"
- cp -r ~ build/outputs/apk/build/pre/*.apk $CIRCLE_ARTIFACTS
- ./gradlew clean :mobile:assembleRelease -PdisablePreDex -Pandroid.threadPoolSize=1 -Dorg.gradle.parallel=false -Dorg.gradle.jvmargs="-Xms2048m -Xmx4608m"
- cp -r ~build/outputs/apk/build/release/*.apk $CIRCLE_ARTIFACTS
assemblePre and assembleRelease are tasks executed in above case. You can try to write custom tasks here.

Proguard not working after update to Google Play Services 11.8.0

After updating Google Play Services to 11.8.0 (from 11.6.2) my builds stop working.
This is what I got:
Unexpected error while computing stack sizes:
Class = [com/google/android/gms/internal/zzao]
Method = [zzf(Ljava/lang/String;)J]
Exception = [java.lang.IllegalArgumentException] (Stack size becomes negative after instruction [23] invokestatic #146 in [com/google/android/gms/internal/zzao.zzf(Ljava/lang/String;)J])
FAILURE: Build failed with an exception.
I'm using Android Studio 3.0.1 with Gradle 4.4.1
My app build.gradle file
buildscript {
repositories {
maven { url "https://maven.fabric.io/public" }
}
dependencies {
classpath "io.fabric.tools:gradle:1.25.1"
}
}
repositories {
maven { url "https://maven.fabric.io/public" }
}
apply plugin: "com.android.application"
apply plugin: "io.fabric"
apply plugin: "let"
apply plugin: "realm-android"
android {
compileSdkVersion project.androidSDKVersion
buildToolsVersion("$androidBuildToolsVersion")
defaultConfig {
versionCode project.versionCode
versionName project.versionName
minSdkVersion project.androidMinSdkVersion
targetSdkVersion project.androidTargetSdkVersion
vectorDrawables.useSupportLibrary = true
resConfigs "pl"
}
buildTypes {
release {
minifyEnabled true
shrinkResources false
crunchPngs false
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro", "proguard-fresco.pro"
signingConfig signingConfigs.release
}
debug {
ext.enableCrashlytics = false
ext.alwaysUpdateBuildId = false
}
}
flavorDimensions "tier", "minApi"
productFlavors {
minApi21 {
minSdkVersion project.androidMinDevSdkVersion
dimension "minApi"
}
minApi16 {
minSdkVersion project.androidMinSdkVersion
dimension "minApi"
}
dev {
multiDexEnabled true
dimension "tier"
}
prod {
multiDexEnabled false
dimension "tier"
}
}
variantFilter { variant ->
def names = variant.flavors*.name
if (names.contains("prod") && names.contains("minApi21")) {
setIgnore(true)
}
}
applicationVariants.all { variant ->
appendVersionNameVersionCode(variant, defaultConfig)
}
lintOptions {
checkReleaseBuilds false
textReport true
textOutput "stdout"
fatal "UnusedResources"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
debugImplementation("com.android.support:multidex:$multidexVersion")
implementation("com.android.support:support-fragment:$androidSupportVersion")
implementation("com.android.support:support-annotations:$androidSupportVersion")
implementation("com.android.support:appcompat-v7:$androidSupportVersion")
implementation("com.android.support:design:$androidSupportVersion")
implementation("com.android.support:recyclerview-v7:$androidSupportVersion")
implementation("com.android.support:cardview-v7:$androidSupportVersion")
implementation("com.android.support:customtabs:$androidSupportVersion")
implementation("com.android.support.constraint:constraint-layout:$constraintLayoutVersion")
implementation("com.android.installreferrer:installreferrer:$installReferrerVersion")
implementation("com.google.android.gms:play-services-analytics:$playServicesVersion")
implementation("com.google.android.gms:play-services-location:$playServicesVersion")
implementation("com.google.android.gms:play-services-ads:$playServicesVersion")
implementation("com.google.android.gms:play-services-auth:$playServicesVersion")
implementation("com.google.firebase:firebase-core:$playServicesVersion")
implementation("com.google.firebase:firebase-messaging:$playServicesVersion")
implementation("com.google.firebase:firebase-config:$playServicesVersion")
implementation("com.google.firebase:firebase-auth:$playServicesVersion")
implementation("com.google.firebase:firebase-invites:$playServicesVersion")
(...) // I had removed other dependencies from the list
}
def appendVersionNameVersionCode(variant, defaultConfig) {
variant.outputs.all { output ->
def versionCode = android.defaultConfig.versionCode
output.versionCodeOverride = versionCode
outputFileName = "${rootProject.name}-${variant.name}-${variant.versionName}-${versionCode}.apk"
}
}
apply plugin: "com.google.gms.google-services"
You don't need to disable optimization entirely, just optimization on the problem class. I had the same issue and got around it by adding the following to the proguard-rules.pro file:
-keep class com.google.android.gms.internal.** { *; }
I have a similar issue. As suggested in this SO thread you just need to add these lines in your build.gradle file :
...
release {
debuggable false
useProguard true
...
}
...
I also had to remove the pro guard optimization by replacing :
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
by
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

Apk size increased drawable-xxxhdpi-v4

I am unable to figure this out. My apk size has increased by at least another MB since the last release. Yes, I have added some new code and couple of vector assets thats it. But there is this drawable-xxxhdpi-v4 which got added to my apk and my png images are repeated there.
Take a look.
Has anybody faced this?
I just cant seem to figure out why is this hapenning. Its not even like these are new images. The old ones which were 0 bytes in this folder are now occupying space.
Gradle version 2.14.1
Plugin version 2.2.3
App build.gradle:
defaultConfig {
applicationId project.APPLICATION_ID
minSdkVersion Integer.parseInt(project.ANDROID_MIN_SDK_VERSION)
targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION)
versionCode Integer.parseInt(project.VERSION_CODE)
versionName project.VERSION_NAME
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
resConfigs "en", "fr"
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath true
}
}
}
lintOptions {
abortOnError false
disable 'MissingTranslation'
}
dataBinding {
enabled = true
}
dexOptions {
preDexLibraries = false
}
// This is handled for you by the 2.0+ Gradle Plugin
aaptOptions {
noCompress "db"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
buildTypes {
def BOOLEAN = "boolean"
def TRUE = "true"
def FALSE = "false"
def LOGGING = "LOGGING"
def STRICT_MODE = "STRICT_MODE"
def DEBUG_MODE = "DEBUG_MODE"
release {
minifyEnabled true
proguardFiles 'proguard-rules.txt', 'proguard-here-sdk.txt'
// Resource shrinking confis
shrinkResources true // remove unused resources
signingConfig signingConfigs.release
debuggable false
buildConfigField BOOLEAN, LOGGING, FALSE
buildConfigField BOOLEAN, STRICT_MODE, FALSE
buildConfigField BOOLEAN, DEBUG_MODE, FALSE
zipAlignEnabled true
applicationVariants.all { variant ->
if (variant.buildType.name == 'release') {
variant.mergeAssets.doLast {
delete(fileTree(dir: variant.mergeAssets.outputDir, includes: ['ic_launcher_debug*']))
}
}
}
}
lintOptions {
disable 'InvalidPackage'
}
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
The below config worked for me
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
Yes. When you compile with Coccoon.io an android version of your app, it happens the same. The size of the app is increased at double. This is not only due to folders like this, but for the libraries Coccoon puts on the app for cordova.
I donĀ“t know if that will help you, but al least is a clue.

Android Studio : How to remove/filter build variants for default debug and release buildTypes and keep only those using custom buildTypes?

I have created custom buildTypes as follows:
buildTypes {
releasefree.initWith(buildTypes.release)
releasefree {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
releasepro.initWith(buildTypes.release)
releasepro {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationIdSuffix ".pro"
}
debugfree.initWith(buildTypes.debug)
debugfree {
shrinkResources true
applicationIdSuffix ".debug"
debuggable true
}
debugpro.initWith(buildTypes.debug)
debugpro {
shrinkResources true
applicationIdSuffix ".pro.debug"
debuggable true
}
}
I am not going to use the default debug and release build types ever and want to remove them from the build variants list. I have more than a few flavors and the list of variants is too huge. Removing the variants with default debug and release types will help as I'm never going to use them.
I tried using variant filter as follows but it did not work
android.variantFilter { variant ->
if(variant.buildType.name.endsWith('Release') || variant.buildType.name.endsWith('Debug')) {
variant.setIgnore(true);
}
}
Is there something wrong in the way I'm filtering the variants or is it just not possible to remove the variants with default debug and release build types.
Figured it out. It was a really silly mistake on my part.
The above variant filter does work. The names are all lower case and the upper case in the strings i was comparing with were the culprit.
Changing to the following (making compare strings lower case) made it work as expected:
android.variantFilter { variant ->
if(variant.buildType.name.endsWith('release') || variant.buildType.name.endsWith('debug')) {
variant.setIgnore(true);
}
}
or this
android.variantFilter { variant ->
if(variant.buildType.name.equals('release') || variant.buildType.name.equals('debug')) {
variant.setIgnore(true);
}
}
With New Variant APIs, it becomes:
androidComponents {
beforeVariants(selector().withBuildType("release")) { variantBuilder ->
variantBuilder.enabled = false
}
}
ref doc
If u want exclude by name use something like this
android.variantFilter { variant ->
if(variant.name.equals("qaRelease")|| variant.name.equals('something')) {
variant.setIgnore(true);
}
}
If you want to ignore specific build variant , Here is details for understanding.
flavorDimensions "client", "server"
productFlavors {
client1 {
manifestPlaceholders variant : 'Client 1'
dimension "client"
applicationId "com.edupointbd.bb"
}
client2 {
manifestPlaceholders variant : 'Client 2'
dimension "client"
applicationId "com.edupointbd.bb"
}
dev {
dimension "server"
}
staging {
dimension "server"
}
production {
dimension "server"
}
}
variantFilter { variant ->
def names = variant.flavors*.name
// To check for a certain build type, use variant.buildType.name == "<buildType>"
if (names.contains("client1") && names.contains("production")) {
// Gradle ignores any variants that satisfy the conditions above.
setIgnore(true)
}
}

Categories

Resources