Dagger 2 singletons no funciona

Utilizando Dagger 2, estoy tratando de inyectar un objeto singleton en múltiples ubicaciones en un solo ámbito. Sin embargo, parece que mi solución en su lugar crea una nueva instancia cada vez.

En este proyecto de prueba, tengo una MainActivity que inicializa el DaggerModule. El DaggerModule proporciona los objetos Box y Cat, con Box tomando Cat como un parámetro. También tengo en Cat en mi MainActivity. Por último, compruebo las referencias de las dos variables de Cat inyectadas (en el cuadro y en MainActivity respectivamente), pero no son la misma instancia.

Si llamo a provideCat () dos veces en MainActivity, se proporciona la misma instancia.

Actividad principal:

public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DaggerModule daggerModule = new DaggerModule(); DaggerComponent daggerComponent = Dagger_DaggerComponent.builder() .daggerModule(daggerModule).build(); // Same Cat instance returned. Cat cat1 = daggerComponent.provideCat(); Cat cat2 = daggerComponent.provideCat(); Log.d("=== cat1: ", cat1.toString()); Log.d("=== cat2: ", cat2.toString()); // Different Cat instance returned. Why? Box box = daggerComponent.provideBox(); Log.d("=== box cat: ", box.getCat().toString()); } } 

 @Module public class DaggerModule { @Provides @Singleton public Cat provideCat() { return new Cat(); } @Provides @Singleton public Box provideBox() { return new Box(provideCat()); } } 

 @Singleton @Component(modules = { DaggerModule.class }) public interface DaggerComponent { Cat provideCat(); Box provideBox(); } 

 public class Cat { @Inject public Cat() { } } 

 public class Box { private Cat mCat; @Inject public Box(Cat cat) { mCat = cat; } public Cat getCat() { return mCat; } } 

¡Gracias por adelantado!

Edit: Funciona si provideBox toma un argumento Cat y lo utiliza para crear el cuadro, en lugar de llamar a provideCat directamente desde dentro de provideBox.

  // Doesn't work, new Cat instance created. @Provides @Singleton public Box provideBox() { return new Box(provideCat()); } 

Vs

  // Works, same singleton injected. @Provides @Singleton public Box provideBox(Cat cat) { return new Box(cat); } 

¿Cuál es la diferencia entre llamar a provideCat en MainActivity y hacerlo desde dentro de provideBox en el DaggerModule? ¿Podría ser que el compilador Dagger no procese el DaggerModule de la misma manera que lo hace con las clases externas y las anotaciones no se aplican si llamo a provideCat?

La razón por la que quería llamar provideCat desde dentro de provideBox era una idea errónea de mi parte de la interfaz de componentes. He entendido mal que la interfaz de Componente no fue realmente implementada por el Módulo, por lo que los argumentos de los métodos del Módulo no tienen que ser declarados en los métodos correspondientes del Componente. Si ese hubiera sido el caso, me habría forzado a crear la instancia de Cat en la llamada a método provideBox de la MainActivity, que quería evitar (por lo tanto llamar provideCat directamente en el método provideBox del Módulo). De hecho, declarar argumentos en los métodos Component incluso hizo que el compilador Dagger no pudiera compilar.

Pero como los métodos Component no toman argumentos, la solución fue simplemente inyectar instancias como argumentos en los métodos del módulo donde sea necesario (en lugar de llamar a los correspondientes métodos de proporcionar dentro del Módulo mismo), y solo tener que llamar a los métodos sin parámetros del Componente De la MainActivity como sigue:

Actividad principal:

 Cat cat = daggerComponent.provideCat(); Box box = daggerComponent.provideBox(); 

Componente:

 Cat provideCat(); Box provideBox(); <- no arguments 

Módulo:

 @Module public class DaggerModule { @Provides @Singleton public Cat provideCat() { return new Cat(); } @Provides @Singleton public Box provideBox(Cat cat) { <- arguments return new Box(cat); } } 

Las instancias singleton Cat de MainActivity y Box son ahora las mismas y no tuve que declararlas desde MainActivity, pero Dagger se las arregló todo. ¡Éxito! Todavía no estoy seguro de por qué proporcionar métodos funcionan de manera diferente cuando se llama desde clases externas que desde dentro del Módulo mismo, sin embargo.

  • ¿Cómo convertir geopoint longitud + latitud a doble?
  • Con Android KitKat chrome: // inspecciona / monitoriza la red de dispositivos, cómo ver todos los datos de la solicitud
  • Propósito de los parámetros de varianza de AsyncTask
  • Guardar ArrayList en la base de datos SQLite en Android
  • La aplicación se bloquea cuando se reanuda
  • ¿Cómo reanudaría la última actividad vista después de que el usuario haya cerrado la aplicación?
  • El soporte de NDK es una característica experimental y todos los casos de uso aún no son compatibles con el error en Android Studio?
  • Ocultar aplicación de Android desde el Administrador de tareas
  • Android: ¿Una forma sencilla de hacer una geofence?
  • AndroidManifest.xml con varias etiquetas de aplicación
  • Convertir una cadena en código fuente Java en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.