Inyección de dependencias con devoluciones de llamada de Hilt y RoomDB en Android
La inyección de dependencia de Dagger siempre ha sido un punto débil en el ampliación de Android: no existe una experiencia recomendada clara sobre cómo organizar los módulos y comentarios extraños para intentar que sea más adecuado para la plataforma Android.
Luego Hitt. La inyección de dependencia es realizable ahora y creo que cualquiera puede encontrarla en 15 minutos. En este artículo, lo guiaré a través de los pasos que tomé para implementar Hilt en una aplicación de Android que usa Room y otras bibliotecas Jetpack.
Como se explica en la recorrido de empuñadura, necesitamos juntar el complemento Gradle y las dependencias al archivo gradle. Es importante tener en cuenta que la compatibilidad con los componentes del ciclo de vida y ViewModel son dependencias independientes, por lo que si se utilizan en una aplicación, el nivel de aplicación build.gradle debería estar así:
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
...
dependencies
....
implementation "com.google.dagger:hilt-android:2.28-alpha"
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"
Siga las instrucciones restantes para configurar el complemento de Gradle.
Mi clase de cojín de datos solía ordenar su propia instancia, pero con Hilt, no necesitamos ningún código internamente de la clase, esto estará en la nueva clase AppModule.
AppModule debe anotarse con @Module y @InstallIn para describir el calibre de los componentes que proporcionará. Ejecuto el código cuando creo la cojín de datos, y una de las respuestas en esta publicación de StackOverflow me proporciona una excelente guisa de hacer esto con Dagger.
@InstallIn(ApplicationComponent::class)
@Module
object AppModule {
lateinit var database: MyDatabase
@Provides
@Singleton
fun provideDatabase(@ApplicationContext context: Context): MyDatabase
// Make sure a read is made before writing so our onCreate callback is executed first
database = Room.databaseBuilder(
context,
MyDatabase::class.java, "database.db"
)
.addCallback(object : RoomDatabase.Callback()
override fun onCreate(db: SupportSQLiteDatabase)
super.onCreate(db)
GlobalScope.launch
MyDatabase.onCreate(database, context) // in companion of MyDatabase
)
.build()
return database
@Provides
fun provideObjectDao(database: MyDatabase): ObjectDao
return database.objectDao()
}
Donado que no podemos aceptar al objeto de la cojín de datos Room en la devolución de indicación, debemos entregarse en manos en el hecho de que luego de que .build () devuelva nuestro objeto de cojín de datos, se llamará a la devolución de indicación. Los campos en AppModule pueden resolver el problema. Al igual que Dagger, puede usar @Providers y @Singleton para anotar los métodos de su proveedor si es necesario.
Encima, preste atención a la anotación @ApplicationContext. Esto proviene de Hilt, lo que significa que no necesitamos crear un proveedor para el contexto.
Para las clases que solo se pueden crear usando su constructor, no es necesario crear módulos y métodos @Provides. Agregue @Inject antaño del constructor de la clase así
class ResourceManager @Inject constructor(@ApplicationContext applicationContext: Context)
// we can use the application context in init or field initialisation
Para cada componente específico de Android que deba inyectarse, usaremos la anotación @AndroidEntryPoint. Por ejemplo, en su evento y sus fragmentos. Incluso si no hay inyección en la «actividad», si necesita inyectar en el fragmento, debe comentar la «actividad».
Ahora, en su clase, puede obtener una instancia de dicho objeto.
@AndroidEntryPoint
class MyFragment : Fragment()
private val viewModel: MyViewModel by viewModels()
@Inject lateinit var database: MyDatabase
...
Pero, ¿cómo inyectar nuestro viewModel? ¿Necesitamos el mismo ViewModelFactory que antaño? Bueno, resulta que Hilt nos lo pone realizable. Necesitamos anotar el constructor de ViewModel con @ViewModelInject, nulo más.
class MyViewModel @ViewModelInject constructor(private val database: MyDatabase) : ViewModel()
...
Esto requiere las dependencias adicionales que mencioné anteriormente.
Estoy impresionado con lo realizable que es Hilt para realizar la inyección de dependencia en Android, ¡y te recomiendo que lo pruebes! Si tiene alguna pregunta o sugerencia, hágamelo conocer.Gracias por percibir