Comenzando con daga-2
Ejemplo de Android
Una de las principales dificultades de escribir una aplicación de Android con Dagger es que el propio sistema operativo crea instancias de muchas clases del marco de trabajo de Android, como Activity
y Fragment
, pero Dagger funciona mejor si puede crear todos los objetos inyectados. En su lugar, debe realizar la inyección de miembros en un método de ciclo de vida.
A partir de la versión 2.10, dagger permite usar dagger.android
, lo que simplifica el uso de dagger con componentes de Android.
** Objetos de actividad de inyección **
-
Instale
AndroidInjectionModule
en el componente de su aplicación para asegurarse de que todos los enlaces necesarios para estos tipos base estén disponibles.@Component(modules = {AndroidInjectionModule.class}) public interface AppComponent {}
-
Comience escribiendo un
@Subcomponent
que implemente [AndroidInjector][AndroidInjector], con un @Subcomponent.Builder
que extienda [AndroidInjector.Builder][AndroidInjector.Builder]: @Subcomponent public interface MainActivityComponent extends AndroidInjector<MainActivity> { @Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder<MainActivity> {} }
-
Después de definir el subcomponente, agréguelo a su jerarquía de componentes definiendo un módulo que vincule el generador de subcomponentes y agregándolo al componente que inyecta su
Aplicación
:@Module(subcomponents = MainActivityComponent.class) public abstract class MainActivityModule { @Binds @IntoMap @ActivityKey(MainActivity.class) abstract AndroidInjector.Factory<? extends Activity> bindMainActivityInjectorFactory(MainActivityComponent.Builder builder); }
-
A continuación, haga que su
Aplicación
implementeHasDispatchingActivityInjector
y@Inject
unDispatchingAndroidInjector<Activity>
para regresar desde el método activityInjector():public class MyApp extends Application implements HasDispatchingActivityInjector { @Inject DispatchingAndroidInjector<Activity> dispatchingActivityInjector; @Override public void onCreate() { super.onCreate(); DaggerAppComponent.create().inject(this); } @Override public DispatchingAndroidInjector<Activity> activityInjector() { return dispatchingActivityInjector; } }
-
Finalmente, en su método
Activity.onCreate()
, llame aAndroidInjection.inject(this)
antes de llamar asuper.onCreate();
:public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(this); super.onCreate(savedInstanceState); } }
Este ejemplo se basó en documentación oficial de la daga. La muestra de trabajo se puede encontrar en github
Descripción y configuración
¿Qué es Daga 2?
El sitio web se describe a sí mismo como:
Dagger es un marco de inyección de dependencia en tiempo de compilación completamente estático
La biblioteca facilita el modelado de gráficos de dependencia, así como la reutilización de objetos. Dado que la reflexión solo se usa en tiempo de compilación como parte del procesamiento de anotaciones, Dagger 2 ha mejorado la velocidad para la inyección de dependencia.
Configuración
1- Agregar soporte para el procesamiento de anotaciones:
Androide
Script build.gradle
de nivel superior:
repositories {
mavenCentral()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
Script build.gradle
de nivel de módulo:
apply plugin: 'com.neenbedankt.android-apt'
Java
plugins {
id "net.ltgt.apt" version "0.5"
}
2- Agregar las dependencias daga 2
dependencies {
compile 'com.google.dagger🗡2.x'
apt 'com.google.dagger:dagger-compiler:2.x'
}
Aprende Dagger2 con un ejemplo simple
He leído y visto muchos tutoriales diferentes de Dagger2, pero la mayoría de ellos son demasiado largos o difíciles de entender, así que decidí escribir un nuevo tutorial simple y breve para Dagger2, espero que les guste.
¿Por qué lo necesitamos?
- Simplifica el acceso a instancias compartidas: proporciona una forma sencilla de obtener referencias a instancias compartidas, por ejemplo, una vez que declaramos en Dagger nuestras instancias únicas, como
SharedPrefrences
, podemos declarar campos con una simple anotación@Inject
. - Pruebas unitarias y de integración más sencillas: podemos cambiar fácilmente los módulos que generan respuestas de red y simular este comportamiento.
Comencemos con un ejemplo simple
La fuente completa del ejemplo está disponible en mi cuenta de GitHub.
Agregar dependencias Dagger2
En primer lugar, debemos agregar las dependencias de Dagger2. Coloque el código debajo de su archivo build.gradle a nivel de módulo.
compile "com.google.dagger🗡$dagger_version"
compile "com.google.dagger:dagger-android:$dagger_version"
compile "com.google.dagger:dagger-android-support:$dagger_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
Si recibe un error como Error: Conflicto con la dependencia ‘com.google.code.findbugs:jsr305’ en el proyecto ‘:aplicación’, debe agregar lo siguiente a su archivo principal app/build.gradle.
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
}
Dos clases simples
Tenemos dos clases (vehículo y motor), la clase de vehículo necesita la clase de motor para funcionar y MainActivity necesita la clase de vehículo. Usaremos Dagger2 para proporcionar estas instancias.
class Vehicle {
private Motor motor;
@Inject
Vehicle(Motor motor) {
this.motor = motor;
}
void increaseSpeed(int value) {
motor.accelerate(value);
}
void decreaseSpeed(int value) {
motor.decelerate(value);
}
void stop() {
motor.brake();
}
int getSpeed() {
return motor.getRpm();
}
}
Clase de motor:
class Motor {
private int rpm;
Motor() {
this.rpm = 0;
}
int getRpm() {
return rpm;
}
void accelerate(int value) {
rpm += value;
}
void decelerate(int value) {
rpm -= value;
}
void brake() {
rpm = 0;
}
}
Clase de módulo
La clase de módulo es responsable de proporcionar objetos que se pueden inyectar. En este ejemplo, queremos inyectar la clase Motor a la clase Vehicle e inyectar la clase Vehicle a MainActivity, por lo que debemos crear MyModule para proporcionar estas instancias.
@Module
class MyModule {
@Provides
@Singleton
Motor provideMotor() {
return new Motor();
}
@Provides
@Singleton
Vehicle provideVehicle() {
return new Vehicle(new Motor());
}
}
@Proporcionar anotación: el objeto devuelto por este método está disponible para inyección de dependencia.
@Interfaz de componentes
Dagger2 necesita una interfaz de componentes para saber cómo debe crear instancias de nuestras clases.
@Singleton
@Component(modules = {MyModule.class})
interface MyComponent {
Vehicle provideVehicle();
void inject(MainActivity main);
}
Interfaz @Component: conexión entre el proveedor del objeto y los objetos que expresan una dependencia.
Inyectar dependencia en Constructor
Al agregar la anotación @Inject, dagger2 puede crear automáticamente una instancia a partir de ese objeto como nuestro objeto Motor de ejemplo en la clase Vehicle.
Inyectar dependencia en MainClass
Dagger2 puede inyectar dependencias automáticamente en los constructores, pero los componentes de Android (actividades, fragmentos, etc.) son instanciados por el marco de trabajo de Android, lo que dificulta el uso de la inyección de dependencia en ellos, por lo que debemos inyectarlos manualmente como se muestra a continuación:
public class MainActivity extends AppCompatActivity {
@Inject
Vehicle vehicle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyComponent component = DaggerMyComponent.builder().build();
component.inject(this);
}
}
Eso es todo, espero que lo disfruten.
Ejemplo básico
Definir un módulo (el modelo de dependencias y su gráfico):
@Module
public class CoffeeModule{
@Provides
public CoffeeMaker provideCoffeeMaker(){
return new CoffeeMaker();
}
@Provides
public Coffee provideCoffee(CoffeeMaker coffeeMaker){
return new Coffee(coffeeMaker);
}
}
Defina un componente:
@Component(
modules={
CoffeeModule.class
}
)
interface CoffeeComponent {
DeveloperActivity inject(DeveloperActivity developerActivity);
}
Inyectar las dependencias:
class DeveloperActivity extends ...{
@Inject
Coffee myCoffee;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerCoffeeComponent.builder()
.coffeeModule(new CoffeeModule())
.build()
.inject();
}
}