How to apply plugin based on build type (Android)

I would like to apply some plugin per build type, something like:

build.gradle:

android{
    ....
    buildTypes{
        release{
            ....
            apply  plugin: 'io.fabric'
        }
        debug{
            ....
            apply plugin: 'testfairy'
        }
    }
    ...
}

But this is applying the plugin to all build types and I’m sure this can be done but I don’t know how to do it.

Thanks

Plugins can’t be applied to only “part of your project”. They are either applied or not. What is the use case where this becomes a problem for you?

Well, these are some uses cases:

1)These plugins are for crash reporting, so I don’t need them to be applied all the time (ex: I don’t need them for my daily local builds because I’m not going to track the crash on those builds, they are for development propose, no for sharing or tracking the crashes).

2)One of the benefits of this chance will be reducing the compilation time (because we need Gradle to apply these plugin), among others.

  1. I just want to apply one of those crash reporting (not both).

Said that, I think I would be useful in some cases to be able to have the chance to apply plugin just for some build types.

A plugin really is a project-scoped concept. A project either has it or not.

But the plugin should allow you to configure it at a finer grained level. For instance, the crash reporting plugin you mentioned should allow you to specify which buildTypes it should apply to. I guess it would be best to get in touch with the maintainers of those plugins. Maybe they already have an option for that.

I realize this is an old issue, but I have a related issue:

I want to apply a plugin at a different point of the file based on the product flavor.

So I have something like this:

android {
    compileSdkVersion 25
    targetSdkVersion 25
    ...
    productFlavors {
    legacy {
        minSdkVersion 9
    }
    current {
        minSdkVersion 14
    }
}
...
dependencies {
    ...
    legacyCompile 'com.google.android.gms:play-services-gcm:10.0.1'
    currentCompile 'com.google.android.gms:play-services-gcm:10.2.6'
}

apply plugin: 'com.google.gms.google-services'

And this does not compile:

Execution failed for task: ':app:processCurrentDebugGoogleServices'.
> Please fix the version conflict either by updating the version of the google-services plugin (information about the latest version is available at https://bintray.com/android/android-tools/com.google.gms.google-services/) or updating the version of com.google.android.gms to 10.2.6.

If I change it to this:

dependencies {
    legacyCompile 'com.google.android.gms:play-services:10.0.1'
}
apply plugin: 'com.google.gms.google-services'
dependencies {
    currentCompile 'com.google.android.gms:play-services:10.2.6'
}

I get the same error except that it tells me to update com.google.android.gms to 10.0.1.

What I want to do is something like this:

dependencies {
    legacyCompile 'com.google.android.gms:play-services:10.0.1'
}
android {
    productFlavors {
        legacy {
            apply plugin: 'com.google.gms.google-services'
        }
    }
}
dependencies {
    currentCompile 'com.google.android.gms:play-services:10.2.6'
}
android {
    productFlavors {
        current {
            apply plugin: 'com.google.gms.google-services'
        }
    }
}

If I understand correctly, this may be an issue with the com.google.gms.google-services plugin, but I would really like to get this working, because my app needs to support ridiculously old versions of Android.

Do you have any suggestions?

Please get in touch with the maintainers of that plugin to sort out why you are getting that error. My explanation above applies to your case as well.

Fair enough. Thanks.

In case anybody else stumbles across this post, I was able to resolve the problem with a lot of persistence and a little bit of magic.

It should be noted that I was following this guide.

Instead of having two separate dependencies:

dependencies {
    ...
    legacyCompile 'com.google.android.gms:play-services-gcm:10.0.1'
    currentCompile 'com.google.android.gms:play-services-gcm:10.2.6'
}

I reduced it to a single dependency with a variable.

ext {
    firebaseVersion = '10.2.6'
}

android {
    productFlavors {
        legacy {
            ...
            firebaseVersion = '10.0.1'
        }
    }
}

dependencies {
    ...
    compile "com.google.android.gms:play-services-gcm:$firebaseVersion"
}

apply plugin: 'com.google.gms.google-services'

For whatever reason, the plugin was happy when I added the dependencies this way.

The snippet above is just overriding a global variable, so you are now always using firebase 10.0.1

What you had before looks right, so please get in touch with the Android community to see why it is not working.

Plug-ins may be a project-level concept, but why? Downloading application of the plug-in based on build type to the plug-in itself doesn’t make any sense considering that Gradle itself is a build configuration tool .

What is the reasoning against letting build.gradle decide when plug-ins are applied?

I dare to remind that we, as customers, do not have a goal of “having a high level concept” but rather to have “a good working solution”. A specific plugin it not an abstract entity, it has a semantic meaning. And as we already have an instrument to declare different semantic buckets - like flavours and release/debug split, it is natural that some plugins may not belong semantically into a flavour.

Here my real world examples:

  • Crashlytics plugin is force-disabled for debug build for me (as it completely mixes up the production reporting)
  • Artifactory plugin has not use for developer build. Yet I cannot deactivate it. The problem here is this is a single plugin which does not support gradle cache which means I get longer compile times for debug, what I am doing much more frequently as building a release. Thus inability to disable plugin literally steals time from my life and from my employer.
1 Like