Last updated 02/23/17
Trying this plugin with a large Android test project
You can try building a mock Android project with a large number of dependencies to compare the effects of the new plugin. The following steps set up the mock project to first run with version 2.3 of the plugin, before building it with 2.5. To get started, open the command line from your desired target directory and run the following commands:
The ./gradlew help command runs through the Gradle configuration phase. To run the project using version 2.5 of the plugin, proceed as follows:
You should see faster configuration times. You can also trigger other build tasks to compare build performance between the two versions.
If you want to compare the benefits of the 2.5 plugin on your own project, read the sections below to learn how to apply the plugin and specific nightly version of Gradle, and adapt your project to some breaking changes.
Because many of the changes are built on very new Gradle APIs that are going through changes, the current plugin requires a very specific nightly build of Gradle.
The current required version is 3.5-20170213202653+0000
To use the nightly build, you need to update the URL in gradle-wrapper.properties as follows:
Although there is no matching versions of Android Studio yet, Android Studio 2.3 is compatible with this version of the plugin.
To apply the plugin to a sample project, change the plugin version in your project-level build.gradle file to the following:
Because the new plugin introduces changes that may break your current build, if you want to use this plugin with a project you are currently developing, we recommend that you conditionally apply the plugin (and configurations specific to the plugin) using a command line argument. For example, add something like the following to your project-level build.gradle file:
To build your project using Android Gradle plugin 2.5.0, simply pass ‘useAlpha’ as an argument as follows:
Note: If you want to switch to using the stable version of the plugin, make sure to also update gradle-wrapper.properties to use a stable version of Gradle. Alternatively, you can simply bypass the wrapper and use a local installation of stable Gradle by running with gradle, instead of ./gradlew.
The following sections describe changes to the build model in version 2.5.0. Code samples in the sections below also show you how to update your build configuration to work with the new plugin and only apply those configurations when you pass the command line argument from the previous section.
Gradle 3.4 introduced a new java-library plugin that includes new configurations allowing control over publication to compile and runtime classpaths (for inter-module dependencies). To be consistent with Gradle’s library plugin, Android plugin 2.5.0 is moving to these dependency configurations.
The charts here explain the relationship between the different configurations.
Note: compile, provided, and apk are currently still available. However, they will disappear in the next major release of the Android plugin.
Just like the current stable versions of the Android plugin, the above configurations are available for flavor- or build type-specific dependencies. For example, you can use api to make the dependency available to all variants, or you can use redApi to make it available to just the ‘red’ variant(s) of the module.
The configuration that is used to resolve all the dependencies of a variant is composed of the above configurations, for the common code/config (api, implementation, compileOnly) as well as the flavor- and build type-specific components (redApi, debugImplementation, …)
These configurations have been renamed:
These configurations are the ones that gets resolved, and Gradle now allows plugins to mark other configurations as non resolvable. The android plugin now does so. Plugins attempting to resolve other configurations (debugCompile for instance) will fail. The result of this resolution would not be accurate or reflect what goes in the variant in all cases anyway.
Plugins or build files that set a resolution strategy on the the resolved configuration will need to be adapted to use the new name. Due to delayed dependency resolution it is now possible to set the resolution strategy while using the variant API. We added getters to access the Configuration objects of a variant.
The following sample shows how to use the new API and how to dynamically use the old or new ways:
Note: The preview version of the new plugin looks for configurations using the old name and will fail if it finds them. Otherwise it would silently ignore the custom resolution strategy. We may change this based on feedback, but we would like to find a way to ease migration.
The following configurations hold the transitive dependencies of a library for consumption by its consumers:
There used to be a single configuration per variant called: <variant>. Since a library can now control what consumers see for compilation, using the implementation and api configurations described in the previous section, there are now two configurations, one for compilation of the consumer(s), and one for runtime.
The charts here explain the relationship between the different configurations.
Plugin 2.5.0 includes a new dependency mechanism that automatically matches variants when consuming a library. This means an app’s debug variant automatically consumes a library’s debug variant. This also works when using flavors—an app’s redDebug variant will consume a library’s redDebug variant.
The default matching strategy requires an exact match of build types and flavors for both the producer and consumers. However, there are some exceptions:
For flavor matching to work between consumer and producer(s), the plugin now requires all flavors to belong to a named flavor dimension—even if you intend to use only a single dimension. This allows a project to properly handle cases where it consumes different producers using different concepts (e.g. color vs shape).
Adding two flavors to a dimension looks something like this:
On the consumer side, for each flavor dimension that is missing (compared to the producers), you need to specify the flavor you want to consume from that dimension. You can do this using the new flavorSelection property:
Note: You can not currently set this per-variant on the consumer side, though we intend to change this in the future. Additionally, if two libraries each configure a ‘color’ dimension, you can not specify the ‘red’ flavor for the first library and the ‘blue’ flavor for the second library.
Note: You cannot easily use the old mechanism for manual variant dependency anymore, even though the Gradle API for it is still present. The configuration provided to the project() DSL now needs to match the consumer in build type and flavors (and other attributes). For instance, it is not possible to make a debug variant consume a release variant through this mechanism because the producer and consumer would not match. (In this case, the name debug refers to the published configuration object mentioned above in the Publishing Dependencies section.) Now that we publish two configurations, one for compiling and one for runtime, this old way of selecting one configuration really doesn’t work anymore.
In order to have your build file support both cases, you can check for ‘useAlpha’ again:
While the default behavior for matching is exact match (“red” must match “red”), Gradle has a new DSL to offer some flexibility around attribute matching. You could for instance setup some rules saying that if a consumer asks for red, then red or magenta are compatible.
The API is here, but it is not trivial to set this up to configure the built-in attributes of the Gradle plugin. We are planning on making this easier in future updates.
Typically, variant dependencies are a combinations of all the component graphs. For example, the blueDebug variant is made up of compile, blueCompile, and debugCompile. All three dependencies are put together and resolved as a single graph.
In previous versions of the plugin, this did not apply to the dependencies used to a embed wear application into the main app. All the <component>WearApp graphs were resolved separately and the highest priority one won. For example, you could do something like the following, and the blue variant(s) would use :wear2 and all other ones would use :wear1.
To support variant aware dependency management for embedded wear apps, plugin 2.5.0 now combines all the graphs together before resolving them, similarly to how other dependencies are handled. So the example above would have to be rewritten as follows:
One benefit though is that if your wearable configures the same flavors as your main app, you don’t need to use the <flavor>WearApp configuration, you can simply specify the wearApp configuration, and each variant of the main app will consume the matching variant on the wearable side:
Separate test modules are now variant aware (see the section above) when using plugin 2.5.0. This means that specifying targetVariant is no longer necessary.
Each variant in the test module will attempt to test a matching variant in the target project. By default, test modules contain only a debug variant, but you can create new build types and new flavors to create new variants to match the tested app project. A connectedCheck task is created for each variant.
To make the Test project test a different build type only, and not the debug one, use VariantFilter to disable the debug variant in the test project.
If the test project is meant to test a single specific variant of an app that contains flavor(s), it is possible to use one or more flavorSelection properties to have the test project target a specific flavor (or set of flavors) without having to declare them itself.
Previously library modules would handle dependencies on local JARs (that is, JAR files somewhere on disk rather than via maven coordinates) in a non-standard way, and would package them inside their AAR. Even in a multi-project build, consumers of the AAR would see these JAR files through the packaged version. Part of this was due to limitations in the Gradle APIs that the Android plugin used to in order to resolve dependencies.
Now that the plugin is using different APIs, consuming projects can see the local JARs as regular transitive dependencies, similar to maven coordinate based dependencies.
To adapt to the new Gradle APIs, the plugin had to change a few aspects to how it handles local JAR files.
Publishing to Maven repo
The Variant API regarding the different outputs of a variant is currently broken. We are making large changes internally to do less things during configuration time, and in some instances, this makes the plugin unable to know all of its outputs up front. We are working on cleaning this up, having some backward compatibility support and new dynamic APIs through call back to offer the same features, but this is not ready yet.
A new incremental dexing pipeline has been implemented. Now the Gradle plugin dex only the class files that have changed. It is enabled by default, but you can disable it by doing one of the following: