This article was translated from Bedanta Bikash Borah. The link to the original article is as follows:

Implementation Vs Api in Android Gradle plugin 3.0

When we use Gradle 3.0 and above plug-ins in Android projects, you will notice that the compile keyword has been deprecated to support implementation and apis. Let’s use an example to understand them.

The sample application (Kotlin) can be found here.

Let’s assume that an Android project contains the following four Library modules:

  • LibraryA
  • LibraryB
  • LibraryC
  • LibraryD

Their dependencies are as follows:

Each Library Module contains a simple class.

LibraryD:

class ClassD {

    fun tellMeAJoke(a):String{
        return "You are funny :D"}}Copy the code

LibraryC:

class ClassC {
    fun tellMeAJoke(a): String {
        return "You are funny :C"}}Copy the code

LibraryB:

class ClassB {

    val b = ClassD()

    fun whereIsMyJoke(a): String {
        return b.tellMeAJoke()
    }
}
Copy the code

LibraryA:

class ClassA {

    val c = ClassC()

    fun whereIsMyJoke(a): String {
        return c.tellMeAJoke()
    }
}
Copy the code

As you can see from these class files, LibraryA and LibraryB depend on LibraryC and LibraryD, respectively. Therefore, you need to add their dependencies to the build.gradle file.

Compile (2.0) or Api (3.0):

The new API keyword in 3.0 has exactly the same meaning as the compile keyword in previous versions. So, if all the compile keywords in the project were replaced by the API, this would work perfectly. Now, let’s rely on LibraryD in LibraryB via the API keyword:

dependencies {
          . . . . 
          api project(path: ':libraryD')}Copy the code

Likewise, add LibraryB to the app module:

dependencies {
          . . . . 
          api project(path: ':libraryB')}Copy the code

LibraryB and LibraryD are now accessible in the app module. In the sample application, the two libraries are accessed as follows:

Implementation (3.0) :

Now it’s time to figure out the difference between Implementation and API. Returning to the above example, let’s now introduce LibraryC in LibraryA via the implementation keyword:

dependencies {
          . . . . 
          implementation project(path: ':libraryC')}Copy the code

The same applies to App modules:

dependencies {
          . . . . 
          implementation project(path: ':libraryA')}Copy the code

Now, if we access in the APP moduleLibraryCAndroid Studio will throw an error:

This means that if we use the implementation keyword instead of the API, LibraryC will not be accessible in the App module. So what’s good about Implementation doing that?

Implementation vs api:

In the first scenario, LibraryD is compiled using the API keyword. Gradle needs to recompile LibraryD whenever any changes are made to the implementation in LibraryD. LibraryB, like all other modules that introduce LibraryB, probably uses the implementation in LibraryD.

But in the second scenario, if you change the code implementation in LibraryC, Gradle will only recompile LibraryC and LibraryA, because any other classes that do not directly rely on LibraryC cannot use any of these implementations.

If you are developing a project with multiple modules, this strategy can significantly speed up the build process. I tried it out in the sample program, and after a few seconds I had some improvements. The following is a build report for all scenarios.

Full build:

Change LibraryD:

Change libraryC:

conclusion

With the Android Gradle plugin version upgraded to 3.0, we just need to replace all compile with implementation keywords and try to build the project. If it works, great. Otherwise, look for any missing dependency libraries that you might be using, and find the host library to import those libraries with the API keyword instead.