Android
Daga 2
Buscar..
Sintaxis
- @Módulo
- @Component (dependencias = {OtherComponent.class}, modules = {ModuleA.class, ModuleB.class})
- DaggerMyComponent.create ()
- DaggerMyComponent.builder (). MyModule (newMyModule ()). Create ()
Observaciones
No confundir con daga por escuadra, el antecesor de daga 2.
Configuración de componentes para inyección de aplicación y actividad.
Un AppComponent
básico que depende de un único AppModule
para proporcionar objetos singleton para toda la aplicación.
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Context provideContext();
Gson provideGson();
}
Un módulo para usar junto con AppComponent
que proporcionará sus objetos singleton, por ejemplo, una instancia de Gson
para reutilizarla en toda la aplicación.
@Module
public class AppModule {
private final Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
@Singleton
@Provides
Gson provideGson() {
return new Gson();
}
@Singleton
@Provides
Context provideContext() {
return mApplication;
}
}
Una aplicación subclasificada para configurar la daga y el componente singleton.
public class App extends Application {
@Inject
AppComponent mAppComponent;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.builder().appModule(new AppModule(this)).build().inject(this);
}
public AppComponent getAppComponent() {
return mAppComponent;
}
}
Ahora es un componente de ámbito de actividad que depende de AppComponent
para obtener acceso a los objetos singleton.
@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
Y un módulo de ActivityModule
reutilizable que proporcionará dependencias básicas, como un FragmentManager
@Module
public class ActivityModule {
private final AppCompatActivity mActivity;
public ActivityModule(AppCompatActivity activity) {
mActivity = activity;
}
@ActivityScope
public AppCompatActivity provideActivity() {
return mActivity;
}
@ActivityScope
public FragmentManager provideFragmentManager(AppCompatActivity activity) {
return activity.getSupportFragmentManager();
}
}
Poniendo todo junto, estamos configurados, podemos inyectar nuestra actividad y ¡asegúrate de usar la misma aplicación Gson
toda la aplicación!
public class MainActivity extends AppCompatActivity {
@Inject
Gson mGson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivityComponent.builder()
.appComponent(((App)getApplication()).getAppComponent())
.activityModule(new ActivityModule(this))
.build().inject(this);
}
}
Alcances personalizados
@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScope {
}
Los ámbitos son solo anotaciones y usted puede crear sus propios cuando sea necesario.
Inyección Constructor
Las clases sin dependencias se pueden crear fácilmente por daga.
public class Engine {
@Inject // <-- Annotate your constructor.
public Engine() {
}
}
Esta clase puede ser proporcionada por cualquier componente. No tiene dependencias en sí y no está dentro del alcance . No hay ningún otro código necesario.
Las dependencias se declaran como parámetros en el constructor. Dagger llamará al constructor y suministrará las dependencias, siempre que esas dependencias puedan proporcionarse.
public class Car {
private Engine engine;
@Inject
public Car(Engine engine) {
this.engine = engine;
}
}
Todos los componentes pueden proporcionar esta clase si este componente también puede proporcionar todas sus dependencias: Engine
en este caso. Dado que el Engine
también puede ser inyectado por el constructor, cualquier componente puede proporcionar un Car
.
Puede utilizar la inyección de constructor siempre que el componente proporcione todas las dependencias. Un componente puede proporcionar una dependencia, si
- Se puede crear mediante inyección de constructor.
- Un módulo del componente puede proporcionarlo.
- puede ser proporcionado por el componente principal (si es un
@Subcomponent
) - puede usar un objeto expuesto por un componente del que depende (dependencias del componente)
Usar @Subcomponent en lugar de @Component (dependencias = {...})
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Context provideContext();
Gson provideGson();
MainActivityComponent mainActivityComponent(ActivityModule activityModule);
}
@ActivityScope
@Subcomponent(modules = ActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
public class MainActivity extends AppCompatActivity {
@Inject
Gson mGson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((App)getApplication()).getAppComponent()
.mainActivityComponent(new ActivityModule(this)).inject(this);
}
}
Cómo agregar Dagger 2 en build.gradle
Desde el lanzamiento de Gradle 2.2, ya no se usa el complemento android-apt. Se debe utilizar el siguiente método de configuración de Dagger 2. Para la versión anterior de Gradle, use el método anterior que se muestra a continuación.
Para Gradle> = 2.2
dependencies {
// apt command comes from the android-apt plugin
annotationProcessor 'com.google.dagger:dagger-compiler:2.8'
compile 'com.google.dagger:dagger:2.8'
provided 'javax.annotation:jsr250-api:1.0'
}
Para Gradle <2.2
Para usar Dagger 2 es necesario agregar el complemento android-apt
, agregar esto a la raíz build.gradle:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
Entonces el build.gradle del módulo de la aplicación debe contener:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
…
}
final DAGGER_VERSION = '2.0.2'
dependencies {
…
compile "com.google.dagger:dagger:${DAGGER_VERSION}"
apt "com.google.dagger:dagger-compiler:${DAGGER_VERSION}"
}
Referencia: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
Creando un componente a partir de múltiples módulos.
Dagger 2 admite la creación de un componente a partir de múltiples módulos. Puedes crear tu componente de esta manera:
@Singleton
@Component(modules = {GeneralPurposeModule.class, SpecificModule.class})
public interface MyMultipleModuleComponent {
void inject(MyFragment myFragment);
void inject(MyService myService);
void inject(MyController myController);
void inject(MyActivity myActivity);
}
Los dos módulos de referencia GeneralPurposeModule
y SpecificModule
se pueden implementar de la siguiente manera:
GeneralPurposeModule.java
@Module
public class GeneralPurposeModule {
@Provides
@Singleton
public Retrofit getRetrofit(PropertiesReader propertiesReader, RetrofitHeaderInterceptor headerInterceptor){
// Logic here...
return retrofit;
}
@Provides
@Singleton
public PropertiesReader getPropertiesReader(){
return new PropertiesReader();
}
@Provides
@Singleton
public RetrofitHeaderInterceptor getRetrofitHeaderInterceptor(){
return new RetrofitHeaderInterceptor();
}
}
SpecificModule.java
@Singleton
@Module
public class SpecificModule {
@Provides @Singleton
public RetrofitController getRetrofitController(Retrofit retrofit){
RetrofitController retrofitController = new RetrofitController();
retrofitController.setRetrofit(retrofit);
return retrofitController;
}
@Provides @Singleton
public MyService getMyService(RetrofitController retrofitController){
MyService myService = new MyService();
myService.setRetrofitController(retrofitController);
return myService;
}
}
Durante la fase de inyección de dependencia, el componente tomará objetos de ambos módulos según las necesidades.
Este enfoque es muy útil en términos de modularidad . En el ejemplo, hay un módulo de propósito general que se utiliza para crear una instancia de componentes como el objeto Retrofit
(usado para manejar la comunicación de la red) y un PropertiesReader
(encargado de manejar los archivos de configuración). También hay un módulo específico que maneja la creación de instancias de controladores y clases de servicio específicos en relación con ese componente de aplicación específico.