sandalone
sandalone

Reputation: 41759

Why does Gradle disregard release{} and implement a rule on debug build as well?

I am not sure if this happened before, but I think it happened after the recent updates of Android Studio and its Gradle.

Namely, I am trying to set the output path of the release APK. So I made a code like this

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        signingConfig signingConfigs.config

        def outputPathName = "./apk-release.apk"
        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                output.outputFile = file(outputPathName)
            }
        }
    }
}

This will move APK from its default location (/build/outputs/apk) and place it next to the build.gradle file.

However, the release{} is being disregarded and Android Studio moves debug build to this location as well also renaming it. So either I create signed APK or press debug icon to test the debug release, the APK is being moved and renamed. And it should stay inside its default location, right?

Why is this happening? A bug inside Android Studio Gradle or a bug in my code?

NOTE: I noticed that the same happens in my other project in which I create a custom name for the APK. It will also rename debug APK and in the same manner disregard release{}.

Android Studio version: 1.3. Preview 5

Upvotes: 0

Views: 176

Answers (1)

CommonsWare
CommonsWare

Reputation: 1007296

the release{} is being disregarded

Not really. Every line of code in build.gradle is executed when the script is processed.

Gradle scripts are not there to execute code at build time. They are there to define the object model of the build process. In Android Studio, Gradle scripts are not read in and interpreted at build time; they are read in when the project opens or when you "Sync Project with Gradle Files". It is that object model that populates things like the Build Variants view.

The release closure is not saying "this is only stuff that should be done on a release build". It merely says "hey, anything you can't recognize, like minifyEnabled, see if that's a property or method or something on this here release object". You could write the beginning portion of your release closure like this:

buildTypes {
    release.minifyEnabled false
    release.proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    release.signingConfig signingConfigs.config
}

or even:

   buildTypes.release.minifyEnabled false
   buildTypes.release.proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
   buildTypes.release.signingConfig signingConfigs.config

if you wanted.

That's why you will usually see that sort of applicationVariants loop at the end of android {}, as (I think) applicationVariants is part of the Gradle for Android plugin DSL, and it will iterate over all application variants.

So, if you only want to affect the release build, in your loop, check the variant for its build type:

    def outputPathName = "./apk-release.apk"
    applicationVariants.all { variant ->
        def name = variant.buildType.name

        if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) {
            return; // Skip debug builds.
        }

        variant.outputs.each { output ->
            output.outputFile = file(outputPathName)
        }
    }

(there's probably a slicker way of filtering this, but this is what I've been using...)

Upvotes: 2

Related Questions