¿Cómo usar Dagger? ¿Cómo configurar Dagger para que funcione en mi proyecto de Android?
Me gustaría usar Dagger en mi proyecto de Android, pero lo encuentro confuso.
EDITAR: Dagger2 también está disponible desde 2015 04 15, ¡y es aún más confuso!
[Esta pregunta es un "trozo" en el que estoy agregando a mi respuesta a medida que aprendí más sobre Dagger1 y aprendí más sobre Dagger2. Esta pregunta es más una guía que una "pregunta".]
android
dependency-injection
dagger
dagger-2
EpicPandaForce
fuente
fuente
ViewModel
yPageKeyedDataSource
? Como uso RxJava2, y quiero que CompositeDisposable sea compartido por ambas clases y si el usuario presiona el botón Atrás, quiero borrar el objeto Disposable. He agregado el caso aquí: stackoverflow.com/questions/62595956/…ViewModel
y tal vez pasar el mismo compositeDisposable como argumento de constructor de su PageKeyedDataSource personalizado, pero realmente no usaría Dagger para esa parte porque entonces necesita subcomponentes subcopiados, y Hilt realmente no lo respaldará fácil para ti.Respuestas:
Guía para Dagger 2.x (Edición revisada 6) :
Los pasos son los siguientes:
1.) agregar
Dagger
a susbuild.gradle
archivos:.
.
2.) Cree su
AppContextModule
clase que proporciona las dependencias.3.) crea la
AppContextComponent
clase que proporciona la interfaz para obtener las clases que son inyectables.3.1.) Así es como crearía un módulo con una implementación:
Tenga cuidado: debe proporcionar la
@Scope
anotación (como@Singleton
o@ActivityScope
) en el@Provides
método anotado del módulo para obtener un proveedor con ámbito dentro de su componente generado; de lo contrario, no tendrá ámbito y obtendrá una nueva instancia cada vez que inyecte.3.2.) Cree un componente de ámbito de aplicación que especifique lo que puede inyectar (esto es lo mismo que
injects={MainActivity.class}
en Dagger 1.x):3.3.) Para las dependencias que puede crear a través de un constructor usted mismo y no querrá redefinir usando un
@Module
(por ejemplo, usa build flavors en su lugar para cambiar el tipo de implementación), puede usar un@Inject
constructor anotado.Además, si usa el
@Inject
constructor, puede usar la inyección de campo sin tener que llamar explícitamentecomponent.inject(this)
:Estas
@Inject
clases de constructor se agregan automáticamente al componente del mismo ámbito sin tener que especificarlas explícitamente en un módulo.Una clase de constructor con
@Singleton
ámbito@Inject
se verá en@Singleton
componentes con ámbito.3.4.) Después de haber definido una implementación específica para una interfaz determinada, así:
Deberá "vincular" la implementación específica a la interfaz con un
@Module
.Un resumen de esto desde Dagger 2.4 es el siguiente:
4.) cree una
Injector
clase para manejar su componente de nivel de aplicación (reemplaza al monolíticoObjectGraph
)(nota:
Rebuild Project
para crear laDaggerApplicationComponent
clase de constructor usando APT)5.) crea tu
CustomApplication
clase6.) agregar
CustomApplication
a suAndroidManifest.xml
.7.) Inyecta tus clases en
MainActivity
8.) ¡Disfruta!
+1.) Puede especificar
Scope
para sus componentes con los que puede crear componentes con ámbito de nivel de actividad . Los subámbitos le permiten proporcionar dependencias que solo necesita para un subámbito determinado, en lugar de para toda la aplicación. Normalmente, cada actividad tiene su propio módulo con esta configuración. Tenga en cuenta que existe un proveedor de ámbito por componente , lo que significa que para retener la instancia para esa actividad, el componente en sí debe sobrevivir al cambio de configuración. Por ejemplo, podría sobrevivir a través deonRetainCustomNonConfigurationInstance()
un alcance de mortero.Para obtener más información sobre el subámbito, consulte la guía de Google . También consulte este sitio sobre métodos de provisión y también la sección de dependencias de componentes ) y aquí .
Para crear un alcance personalizado, debe especificar la anotación de calificador de alcance:
Para crear un subámbito, debe especificar el ámbito de su componente y especificarlo
ApplicationComponent
como su dependencia. Obviamente, también debe especificar el subámbito en los métodos del proveedor del módulo.Y
Tenga en cuenta que sólo un componente restringidos se puede especificar como una dependencia. Piense en ello exactamente como en Java no se admite la herencia múltiple.
+2.) Acerca de
@Subcomponent
: esencialmente, un ámbito@Subcomponent
puede reemplazar la dependencia de un componente; pero en lugar de utilizar un constructor proporcionado por el procesador de anotaciones, necesitaría utilizar un método de fábrica de componentes.Así que esto:
Se convierte en esto:
Y esto:
Se convierte en esto:
+3.): Consulte también otras preguntas de Stack Overflow sobre Dagger2, ya que proporcionan mucha información. Por ejemplo, mi estructura actual de Dagger2 se especifica en esta respuesta .
Gracias
Gracias por las guías de Github , TutsPlus , Joe Steele , Froger MCS y Google .
También para esta guía de migración paso a paso que encontré después de escribir esta publicación.
Y para la explicación del alcance de Kirill.
Aún más información en la documentación oficial .
fuente
DaggerApplicationComponent
es autogenerado por APT en la compilación, pero lo agregaré .Guía para Dagger 1.x :
Los pasos son los siguientes:
1.) agregar
Dagger
albuild.gradle
archivo para las dependenciasAdemás, agregue
packaging-option
para evitar un error sobreduplicate APKs
.2.) crea una
Injector
clase para manejar elObjectGraph
.3.) Cree un
RootModule
para vincular sus futuros módulos. Tenga en cuenta que debe incluirinjects
para especificar cada clase en la que utilizará la@Inject
anotación, porque de lo contrario Dagger lanzaRuntimeException
.4.) En caso de que tenga otros submódulos dentro de sus módulos especificados en su raíz, cree módulos para esos:
5.) crea los módulos hoja que reciben las dependencias como parámetros del constructor. En mi caso, no hubo dependencia circular, así que no sé si Dagger puede resolver eso, pero lo encuentro poco probable. Los parámetros del constructor también deben proporcionarse en un módulo por Dagger, si lo especifica
complete = false
, también puede estar en otros módulos.6.) Amplíe
Application
e inicialice el archivoInjector
.7.) En su
MainActivity
, llame al Inyector en elonCreate()
método.8.) Úselo
@Inject
en suMainActivity
.Si recibe el error
no injectable constructor found
, asegúrese de no olvidar las@Provides
anotaciones.fuente
Android Bootstrap
. Entonces, les damos crédito por resolverlo. Usos de soluciónDagger v1.2.2
.dagger-compiler
debería ser de loprovided
contrario, se incluirá en la aplicación y está bajo licencia GPL.