Hilt: la nueva biblioteca DI oficial para Android (Parte 2) | Via PRANAY Patel | Simform Engineering | Agosto de 2021
Utilice calificadores:
El calificador es un comentario que se utiliza para identificar el enlace.
paso 1: Crea un archivo nuevo LoggerDataSource.kt
Tiene una interfaz con métodos de base de datos generales:
interface LoggerDataSource
fun addLog(message: String)
fun getAllLogs(callback:(List<Log>)->Unit)
fun removeLogs()
Paso 2: Abierto LogsFragment
Y crea el tipo de variable del registrador LoggerDataSource
:
@AndroidEntryPoint
class LogsFragment : Fragment() @Inject lateinit var logger: LoggerDataSource
...
Paso 3: Hacer la misma cosa ButtonsFragment
:
@AndroidEntryPoint
class ButtonsFragment : Fragment() @Inject lateinit var logger: LoggerDataSource
...
el cuarto paso: Como creamos un comn LoggerDataSource
La interfaz ahora está hecha LoggerLocalDataSource
Implementar LoggerDataSource
Y cubra el método requerido.
@Singleton
class LoggerLocalDataSource @Inject constructor(
private val logDao: LogDao
) : LoggerDataSource
...
override fun addLog(msg: String) ...
override fun getAllLogs(callback: (List<Log>) -> Unit) ...
override fun removeLogs() ...
Paso 5: Para administrar fuentes de datos en memoria, cree un nuevo LoggerInMemoryDataSource
Bajo el paquete de datos y lograr lo mismo LoggerDataSource
interfaz:
- Dado que necesitamos el alcance del alcance insuficiente de esta actividad, necesitamos utilizar
@ActivityScoped
:
@ActivityScoped
class LoggerInMemoryDataSource @Inject constructor(
) : LoggerDataSource private val logs = LinkedList<Log>() override fun addLog(msg: String)
logs.addFirst(Log(msg, System.currentTimeMillis()))
override fun getAllLogs(callback: (List<Log>) -> Unit)
callback(logs)
override fun removeLogs()
logs.clear()
Paso 6: Cómo crear dos implementaciones diferentes para la misma interfaz (aquí: LoggerDataSource
)? Para ello, podemos crear enlaces para dos módulos en el mismo archivo.Así que ahora crea un nuevo archivo. LoggingModule.kt
bajo di
paquete.
package com.example.android.hilt.di@InstallIn(ApplicationComponent::class)
@Module
abstract class LoggingDatabaseModule @Singleton
@Binds
abstract fun bindDatabaseLogger(impl: LoggerLocalDataSource): LoggerDataSource
@InstallIn(ActivityComponent::class)
@Module
abstract class LoggingInMemoryModule @ActivityScoped
@Binds
abstract fun bindInMemoryLogger(impl: LoggerInMemoryDataSource): LoggerDataSource
⚠️ En esta etapa, mientras construye el proyecto, obtendrá DuplicateBindings
¡Error! ¿Por qué?
razón: Porque tenemos LoggerDataSource
Inyectar en ambos fragmentos pero Hilt no sabe qué implementación usar, ¡porque hay dos enlaces del mismo tipo! aquí Calificatorio ¡En el papel!
¿Para qué sirven los calificadores?: Se usa para decirle a Hilt que proporcione diferentes implementaciones del mismo tipo (enlace múltiple).P.ej LoggerDataSource
¡Creemos que el clasificatorio es solo un comentario! Veamos cómo usarlo.
Déjanos entrar LoggingModule.kt
documento:
@Qualifier
annotation class InMemoryLogger@Qualifier
annotation class DatabaseLogger
Ahora estos calificadores deben ser comentados. @Binds
Proporcione cada función implementada.Entonces el código completo LoggingModule.kt
voluntad:
@Qualifier
annotation class InMemoryLogger@Qualifier
annotation class DatabaseLogger
@InstallIn(ApplicationComponent::class)
@Module
abstract class LoggingDatabaseModule @DatabaseLogger
@Singleton
@Binds
abstract fun bindDatabaseLogger(impl: LoggerLocalDataSource): LoggerDataSource
@InstallIn(ActivityComponent::class)
@Module
abstract class LoggingInMemoryModule @InMemoryLogger
@ActivityScoped
@Binds
abstract fun bindInMemoryLogger(impl: LoggerInMemoryDataSource): LoggerDataSource
A continuación, debemos usar el mismo calificador al inyectar la clase.En nuestro ejemplo, si usamos LoggerInMemoryDataSource
En nuestros dos fragmentos, necesitamos agregar calificadores @Inject
:
LogsFragment.kt
:
@AndroidEntryPoint
class LogsFragment : Fragment() @InMemoryLogger
@Inject lateinit var logger: LoggerDataSource
...
ButtonsFragment.kt
:
@AndroidEntryPoint
class ButtonsFragment : Fragment() @InMemoryLogger
@Inject lateinit var logger: LoggerDataSource
...
Si desea cambiar la implementación de la base de datos (consulte bindDatabaseLogger
) Quieres usar, solo necesitas anotar los campos inyectados @DatabaseLogger
reemplazar @InMemoryLogger
.
Entonces ahora puede ejecutar la aplicación y verificar todos los registros.