Una guía pragmática de Hilt con Kotlin | de Filip Stanis | Desarrolladores de Android | Noviembre de 2020

Una forma fácil de usar Dependency Injection en su aplicación de Android

Hilt es una nueva biblioteca de inyección de dependencias construida sobre Dagger que facilita su uso en aplicaciones de Android. Esta guía muestra las características principales con algunos fragmentos de código para ayudarlo a comenzar a usar Hilt en su proyecto.

Para configurar Hilt en su aplicación, primero siga la guía de configuración de Gradle Build.

Una vez que haya instalado todas las dependencias y complementos, escriba su archivo Application clase con @HiltAndroidApp utilizar empuñadura. No es necesario hacer nada más ni invocarlo directamente.

Cuando escribe código que usa la inyección de dependencia, hay dos componentes principales en los que pensar:

  1. Clases que tienen dependencias que desea inyectar.
  2. Clases que se pueden inyectar como dependencias.

Estos no son mutuamente excluyentes y, en muchos casos, su clase es inyectable y tiene adicciones.

Hacer una adicción inyectable

Para crear algo inyectable en Hilt, debe decirle a Hilt cómo crear una instancia de esa cosa. Estas instrucciones se llaman ataques.

Hay tres formas de definir un enlace en Elsa.

  1. Tenga en cuenta el constructor con @Inject
  2. Utilizar @Binds en una forma
  3. Utilizar @Provides en una forma

Tenga en cuenta el constructor con @Inject

Cualquier clase puede tener un constructor anotado con @Inject lo que lo hace disponible como dependencia en cualquier parte del proyecto.

Usando un formulario

Las otras dos formas de crear algo inyectable en Hilt implican el uso de formularios.

Un módulo de Hilt se puede considerar como una colección de «recetas» que le dicen a Hilt cómo crear una instancia de algo que no tiene un constructor, como una interfaz o un servicio del sistema.

Además, cualquier módulo se puede reemplazar en las pruebas con un módulo diferente. Esto hace que sea más fácil, por ejemplo, reemplazar implementaciones de interfaz con simulacros.

Los módulos se instalan en un componente de Hilt especificado utilizando el @InstallIn anotación. Explicaré esto con más detalle más adelante.

Opción 1: usar @Binds para crear la asociación para una interfaz

Si quieres usar OatMilk en código cuando Milk es necesario, cree un método abstracto dentro de un módulo y anótelo con @Binds. Tenga en cuenta que OatMilk debe ser inyectable en sí mismo para que esto funcione, lo que puede lograr notando su constructor con @Inject.

Opción 2: usar @Provides para crear una función de fábrica

Cuando no se puede crear una instancia directamente, puede crear un proveedor. Un proveedor es una función de fábrica que devuelve una instancia de un objeto.

Un ejemplo de esto es un servicio de sistema como ConnectivityManager que debe obtenerse de un contexto.

los Context el artículo es inyectable de forma predeterminada, siempre que lo anote con uno @ApplicationContext o @ActivityContext.

Inyectar una adicción

Una vez que sus adicciones sean inyectables, puede inyectarlas usando Hilt de dos maneras.

  1. Como parámetros de constructor
  2. Como campos

⮕ Como parámetros de constructor

Si el fabricante está marcado con @Inject, Hilt inserta todos los parámetros basados ​​en los enlaces definidos para esos tipos.

⮕ Campos similares

Si la clase es un punto de entrada, especifique aquí usando el @AndroidEntryPoint anotación (más sobre esto en la siguiente sección), todos los campos anotados con @Inject se inyectan.

Campos anotados con @Inject debe ser público. También conviene prepararlos lateinit para evitar hacerlos anulables, ya que su valor inicial antes de la inyección es null.

Tenga en cuenta que insertar dependencias como campos solo es útil cuando su clase necesita tener un constructor sin parámetros, como Activity. En la mayoría de los casos, recomendamos que inyecte a través de los parámetros del constructor.

Punto de entrada

Recuerda cuando dije que en muchos casos tu clase se crea por inyección es ¿Tiene dependencias inyectadas en él? En algunos casos tendrás una clase que no es creado a través de la inyección de dependencias, pero todavía tiene dependencias inyectadas en él. Un buen ejemplo de esto son las actividades, que normalmente son creadas por el marco de Android en lugar de Hilt.

Estas clases son Puntos de entrada en el cuadro de dependencias de Hilt y Hilt, necesita saber que tienen dependencias que deben inyectarse.

⮕ Punto de entrada de Android

La mayoría de sus puntos de entrada serán uno de los denominados puntos de entrada de Android:

  • Ocupaciones
  • Fragmento
  • Ver
  • Servicio
  • Receptor de radiodifusión

Si es así, escríbalo con @AndroidEntryPoint.

⮕ Otros puntos de entrada

La mayoría de las aplicaciones solo necesitan puntos de entrada de Android, pero si está interactuando con bibliotecas que no son de Dagger o componentes de Android que aún no son compatibles con Hilt, es posible que deba crear su propio punto de entrada para acceder manualmente al gráfico de Hilt. Puede leer más sobre cómo convertir clases arbitrarias en puntos de entrada.

ViewModel

UNA ViewModel es un caso especial: no se crea una instancia directamente, ya que el marco tiene que crearlos, pero tampoco es un punto de entrada de Android. En lugar, ViewModels usa el especial @ViewModelInject anotación que permite a Hilt inyectarles dependencias cuando se crean usando by viewModels(), similar a me gusta @Inject funciona para otras clases.

Para que esto funcione, deberá agregar algunas dependencias más. Para obtener más información, consulte las integraciones de Hilt y Jetpack.

Componentes

Cada módulo se instala dentro de un componente Hilt, especificado mediante @InstallIn(<component>). El componente del módulo se utiliza principalmente para evitar la inserción accidental de una dependencia en el lugar incorrecto. Por ejemplo, @InstallIn(ServiceComponent.class) evitaría que el enlace y el proveedor del módulo anotado se utilicen en una actividad.

Además, puede definir un enlace para el componente en el que se encuentra el módulo. Lo que me lleva a …

Areas

De forma predeterminada, las asociaciones no tienen ámbito. En el ejemplo anterior, esto significa que cada vez que se inyecta Milk, obtén una nueva instancia de OatMilk. Si agrega el @ActivityScoped anotación, el alcance de la asociación un ActivityComponent.

Ahora que su formulario tiene alcance, Hilt solo creará uno OatMilk por instancia de negocio. Aparte de eso OatMilk La instancia estará ligada al ciclo de vida de esa actividad; se creará cuando la actividad onCreate() se llama y se destruye cuando la actividad es onDestroy() se llama.

En este caso, ambos milk es moreMilk apuntará a lo mismo OatMilk ejemplo. Sin embargo, si tiene varias instancias de LatteActivity, cada uno tendrá su propia instancia de OatMilk.

En consecuencia, otras dependencias inyectadas en esta actividad tienen el mismo alcance y, por lo tanto, también usarán la misma instancia de OatMilk:

El alcance depende del componente en el que esté instalado el módulo, p. Ej. @ActivityScoped solo se puede aplicar a asociaciones dentro de un módulo instalado dentro ActivityComponent.

El alcance también determina el ciclo de vida de las instancias inyectadas: en este caso, la instancia única de Milk usado por Fridge es LatteActivity se crea cuando onCreate() es requerido LatteActivity – y destruido en su onDestroy(). Esto también significa nuestro Milk no «sobreviviría» a un cambio de configuración, ya que esto implicaría una llamada a onDestroy() sobre la actividad. Puede solucionar esto mediante el uso de un alcance con un ciclo de vida más largo, por ejemplo @ActivityRetainedScope.

Para obtener una lista de los ámbitos disponibles, los componentes a los que corresponden y los ciclos de vida correspondientes que siguen, consulte Componentes de Hilt.

Inyección del proveedor

A veces, desea un control más directo sobre la creación de instancias inyectadas. Por ejemplo, es posible que desee inyectar una o más instancias de algo solo cuando sea necesario, según su lógica empresarial. En este caso, puede utilizar dagger.Provider.

La inyección de proveedor se puede utilizar independientemente de cuál sea la dependencia y cómo se inyecte. Todo lo que se pueda inyectar se puede envolver dentro Provider<…> para que use la inyección del proveedor en su lugar.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *