Esta respuesta va a demostrar la diferencia entre implementation
, api
y compile
en un proyecto.
Digamos que tengo un proyecto con tres módulos Gradle:
- aplicación (una aplicación de Android)
- myandroidlibrary (una biblioteca de Android)
- myjavalibrary (una biblioteca de Java)
app
tiene myandroidlibrary
como dependencias. myandroidlibrary
tiene myjavalibrary
como dependencias.

myjavalibrary
tiene una MySecret
clase
public class MySecret {
public static String getSecret() {
return "Money";
}
}
myandroidlibrary
tiene una MyAndroidComponent
clase que manipula el valor de la MySecret
clase.
public class MyAndroidComponent {
private static String component = MySecret.getSecret();
public static String getComponent() {
return "My component: " + component;
}
}
Por último, app
solo le interesa el valor demyandroidlibrary
TextView tvHelloWorld = findViewById(R.id.tv_hello_world);
tvHelloWorld.setText(MyAndroidComponent.getComponent());
Ahora, hablemos de las dependencias ...
app
necesita consumir :myandroidlibrary
, así que en app
build.gradle uso implementation
.
( Nota : también puedes usar api / compile. Pero mantén ese pensamiento por un momento).
dependencies {
implementation project(':myandroidlibrary')
}

¿Cómo crees que myandroidlibrary
debería ser build.gradle? ¿Qué alcance debemos usar?
Tenemos tres opciones:
dependencies {
// Option #1
implementation project(':myjavalibrary')
// Option #2
compile project(':myjavalibrary')
// Option #3
api project(':myjavalibrary')
}

¿Cuál es la diferencia entre ellos y qué debo usar?
Compilar o API (opción # 2 o # 3)

Si estás usando compile
o api
. Nuestra aplicación de Android ahora puede acceder a la myandroidcomponent
dependencia, que es una MySecret
clase.
TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can access MySecret
textView.setText(MySecret.getSecret());
Implementación (opción # 1)

Si está utilizando la implementation
configuración, MySecret
no está expuesto.
TextView textView = findViewById(R.id.text_view);
textView.setText(MyAndroidComponent.getComponent());
// You can NOT access MySecret
textView.setText(MySecret.getSecret()); // Won't even compile
Entonces, ¿qué configuración debe elegir? Eso realmente depende de su requerimiento.
Si desea exponer dependencias use api
o compile
.
Si no desea exponer dependencias (ocultar su módulo interno), use implementation
.
Nota:
Esto es solo una esencia de las configuraciones de Gradle, consulte la Tabla 49.1. Complemento de la Biblioteca Java: configuraciones utilizadas para declarar dependencias para una explicación más detallada.
El proyecto de muestra para esta respuesta está disponible en https://github.com/aldoKelvianto/ImplementationVsCompile