Cómo obtener MainActivity dentro de un módulo usando AndroidInjector

Con dagger-android uno ahora puede simplemente escribir lo siguiente e inyectar con éxito las dependencias de la aplicación:

 @Module public abstract class MainActivityModule { @ContributesAndroidInjector abstract MainActivity contributesMainActivity(); } @Singleton @Component(modules = { AndroidSupportInjectionModule.class, AndroidInjectionModule.class, AppModule.class, MainActivityModule.class }) public interface ApplicationComponent { void inject(BaseApplication baseApplication); @Component.Builder interface Builder { @BindsInstance Builder application(Application application); ApplicationComponent build(); } } @Module public abstract class AppModule {} public class MainActivity extends AppCompatActivity implements HasSupportFragmentInjector { @Inject DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector; @Inject Whatever whatever; @Override protected void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public AndroidInjector<Fragment> supportFragmentInjector() { return dispatchingAndroidInjector; } } public class BaseApplication extends Application implements HasActivityInjector { @Inject DispatchingAndroidInjector<Activity> dispatchingAndroidInjector; @Override public AndroidInjector<Activity> activityInjector() { return dispatchingAndroidInjector; } @Override public void onCreate() { DaggerApplicationComponent.builder() .application(this) .build() .inject(this); super.onCreate(); } } public class Whatever { private final FragmentManager fragmentManager; @Inject Whatever(MainActivity mainActivity) { this.fragmentManager = mainActivity.getSupportFragmentManager(); } } 

Un ejemplo muy trivial. Básicamente cable todo para poder conseguir el objeto Whatever con el administrador de fragmento correcto inyectado. Esto está bien y funciona.

Sin embargo, ¿qué pasa si quiero usar la actividad principal dentro de un módulo? Decir que quiero hacer realmente Whatever que exponga explícitamente la dependencia al gestor de fragmentos cambiando el argumento del constructor:

 @Inject Whatever(FragmentManager fragmentManager) {...} 

Ahora necesito proporcionar esta dependencia. ¿Cómo se hace? Así que he intentado lo siguiente:

 @Module public abstract class MainActivityModule { @ContributesAndroidInjector abstract MainActivity contributesMainActivity(); @Provides static FragmentManager providesFragmentManager(MainActivity activity) { return activity.getSupportFragmentManager(); } } 

Ahora dagger se queja de que no puede encontrar un @Providers para MainActivity . Pensé que el método @ContributesAndroidInjector sería capaz de proporcionar la actividad. También estoy un poco perplejo en cuanto a cómo no tiene ningún problema de inyectar la dependencia en el primer caso, pero ahora no puede hacerlo.

También he intentado construir una fábrica para esto, algo así como:

 public FragmentManagerFactory { private final FragmentManager fm; @Inject FragmentManagerFactory(MainActivity mainActivity){ this.fm = mainActivity.getSupportFragmentManager(); } public FragmentManager get() { return fm; } } @Module public abstract class MainActivityModule { @ContributesAndroidInjector abstract MainActivity contributesMainActivity(); @Provides static FragmentManager providesFragmentManager(FragmentManagerFactory fragmentManagerFactory) { return fragmentManagerFactory.get(); } } 

Que termina en el mismo error.

¿Alguien ha logrado hacer esto? Antes de que fuera bastante fácil, uno sólo construiría el módulo con la instancia de MainActivity almacenaría en un campo y proporcionaría eso. Ahora … todo sucede detrás de las cortinas.

Apreciaría mucho ayuda!

En mi configuración tengo un di/ paquete en la raíz de sub-di-packages en mi ui/ package. En el paquete ui/di he declarado el siguiente módulo y componente:

 @dagger.Module public class MainActivityModule { @Provides FragmentManager provideFragmentManager(MainActivity mainActivity) { return mainActivity.getSupportFragmentManager(); } } 

MainActivitySubcomponent

 @Subcomponent(modules = MainActivityModule.class) public interface MainActivitySubcomponent extends AndroidInjector<MainActivity> { @Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder<MainActivity> { } } 

en el paquete di nivel superior donde guardo mi ApplicationComponent , tengo un module adicional

 @Module(subcomponents = {MainActivitySubcomponent.class }) public abstract class BuildersModule { @Binds @IntoMap @ActivityKey(MainActivity.class) abstract AndroidInjector.Factory<? extends Activity> mainActivityBinder(MainActivitySubcomponent.Builder builder); } 

Y como se puede imaginar BuildersModule , es parte de @Component(modules = { de ApplicationComponent .


Exención de responsabilidad: Soy bastante nuevo en dagger2 y todavía estoy tratando de averiguar un montón de cosas. Puede haber mejores maneras de lograr lo que necesita.

  • Dagger 2 no está generando mi clase de componente
  • Implementación de GoogleApiClient en Android mvp con daga?
  • Dagger 2 con Android Studio 3.0 Preview (Canary 2) usando annotationProcessor en lugar de android-apt
  • Androide plain Junit con Daga 2
  • MVP de Android con Dagger 2 - Actividad con múltiples fragmentos
  • Dagger 2 problem @ Injecting FirebaseMessagingService
  • MVP, establecer la opinión del presentador de nulo en destruir?
  • Realm.io / Dagger / Databinding en el mismo proyecto
  • Android molesta una Dagger2 inyecta dependencia para una prueba de Espresso
  • Cómo inyectar un presentador en una vista (patrón MVP) usando Dagger2
  • Dagger 2 Build IllegalArgumentException compileDebugJavaWithJavac
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.