After updating to Android Studio 3.0 and creating a new project, I noticed that in build.gradle
there is a new way to add new dependencies instead of comp
tl;dr
Just replace:
compile
with implementation
(if you don't need transitivity) or api
(if you need transitivity)testCompile
with testImplementation
debugCompile
with debugImplementation
androidTestCompile
with androidTestImplementation
compileOnly
is still valid. It was added in 3.0 to replace provided and not compile. (provided
introduced when Gradle didn't have a configuration name for that use-case and named it after Maven's provided scope.)It is one of the breaking changes coming with Android Gradle plugin 3.0 that Google announced at IO17.
The compile
configuration is now deprecated and should be replaced by implementation
or api
From the Gradle documentation:
dependencies { api 'commons-httpclient:commons-httpclient:3.1' implementation 'org.apache.commons:commons-lang3:3.5' }
Dependencies appearing in the
api
configurations will be transitively exposed to consumers of the library, and as such will appear on the compile classpath of consumers.Dependencies found in the
implementation
configuration will, on the other hand, not be exposed to consumers, and therefore not leak into the consumers' compile classpath. This comes with several benefits:
- dependencies do not leak into the compile classpath of consumers anymore, so you will never accidentally depend on a transitive dependency
- faster compilation thanks to reduced classpath size
- less recompilations when implementation dependencies change: consumers would not need to be recompiled
- cleaner publishing: when used in conjunction with the new maven-publish plugin, Java libraries produce POM files that distinguish exactly between what is required to compile against the library and what is required to use the library at runtime (in other words, don't mix what is needed to compile the library itself and what is needed to compile against the library).
The compile configuration still exists, but should not be used as it will not offer the guarantees that the
api
andimplementation
configurations provide.
Note: if you are only using a library in your app module -the common case- you won't notice any difference.
you will only see the difference if you have a complex project with modules depending on each other, or you are creating a library.
Since version 5.6.3 Gradle documentation provides simple rules of thumb to identify whether an old compile
dependency (or a new one) should be replaced with an implementation
or an api
dependency:
- Prefer the
implementation
configuration overapi
when possibleThis keeps the dependencies off of the consumer’s compilation classpath. In addition, the consumers will immediately fail to compile if any implementation types accidentally leak into the public API.
So when should you use the
api
configuration? An API dependency is one that contains at least one type that is exposed in the library binary interface, often referred to as its ABI (Application Binary Interface). This includes, but is not limited to:
- types used in super classes or interfaces
- types used in public method parameters, including generic parameter types (where public is something that is visible to compilers. I.e. , public, protected and package private members in the Java world)
- types used in public fields
- public annotation types
By contrast, any type that is used in the following list is irrelevant to the ABI, and therefore should be declared as an
implementation
dependency:
- types exclusively used in method bodies
- types exclusively used in private members
- types exclusively found in internal classes (future versions of Gradle will let you declare which packages belong to the public API)
Gradle 3.0
introduced next changes:
compile
-> api
api
keyword is the same as deprecated compile
compile
-> implementation
Is preferable way because has some advantages. implementation
expose dependency only for one level up at build time (the dependency is available at runtime). As a result you have a faster build(no need to recompile consumers which are higher then 1 level up)
provided
-> compileOnly
This dependency is available only in compile time(the dependency is not available at runtime). This dependency can not be transitive and be .aar
. It can be used with compile time annotation processor and allows you to reduce a final output file
compile
-> annotationProcessor
Very similar to compileOnly
but also guarantees that transitive dependency are not visible for consumer
apk
-> runtimeOnly
Dependency is not available in compile time but available at runtime.
[POM dependency type]