What's the difference between implementation and compile in Gradle?

前端 未结 9 1485
北荒
北荒 2020-11-22 03:01

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

相关标签:
9条回答
  • 2020-11-22 03:29

    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 and implementation 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.

    0 讨论(0)
  • 2020-11-22 03:38

    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 over api when possible

    This 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)
    0 讨论(0)
  • 2020-11-22 03:43

    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]

    0 讨论(0)
提交回复
热议问题