38
Utilizando WorkManager com Hilt - Injeção de dependência na classe Worker
WorkManager é uma API para programação de tarefas assíncronas que nos permite programar tarefas para serem executadas mesmo quando o app é fechado.
Hilt é uma biblioteca de injeção de dependências para android criada com base na biblioteca Dagger.
Nesse artigo eu vou demonstrar como utilizar injeção de dependências na classe Worker da API WorkManager com Hilt
build.gradle(Module)
dependencies {
implementation "androidx.work:work-runtime-ktx:2.5.0"
androidTestImplementation "androidx.work:work-testing:2.5.0"
testImplementation "androidx.work:work-testing:2.5.0"
}
class SomeWork(appContext: Context, workerParams: WorkerParameters):
Worker(appContext, workerParams) {
override fun doWork(): Result {
val user: User = User("John Doe", 32)
print(user.toString())
return Result.success()
}
}
No exemplo acima a classe SomeWork
que estende Worker
instancia um objeto do tipo User e imprime o resultado no terminal. Nos exemplos a seguir veremos como passar User via parâmetro com hilt
//Criando request
val doSomeWorkRequest: WorkRequest =
PeriodicWorkRequestBuilder<SomeWork>(15,TimeUnit.Minutes)
.build()
//Enviando para o sistema
WorkManager.getInstance(context)
.enqueueUniquePeriodicWork(
"AppNameSomeWork",
ExistingPeriodicWorkPolicy.KEEP,
doSomeWorkRequest
)
No exemplo acima foi criada uma requisição que irá se repetir a cada 15 minutos que é o tempo mínimo permitido pelo sistema. A cada 15 minutos será executada a linha de código print(user.toString())
dentro no método doWork()
na classe SomeWork
build.gradle(Project)
buildscript {
//...
dependencies {
//...
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.37'
}
}
build.gradle(Module)
//...
plugins {
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
android {
//...
//O Hilt usa recursos do Java 8, ativar o Java 8
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
//...
annotationProcessorOptions {
//O importante aqui é substituir = por += caso seu
//projeto não esteja assim
arguments += [... ]
}
}
}
kapt {
correctErrorTypes true
}
dependencies {
//Dagger - Hilt
implementation 'com.google.dagger:hilt-android:2.37'
kapt 'com.google.dagger:hilt-compiler:2.37'
kapt 'androidx.hilt:hilt-compiler:1.0.0'
implementation 'androidx.hilt:hilt-work:1.0.0'
implementation 'androidx.hilt:hilt-navigation-compose:1.0.0-alpha03'
}
Adicione as dependências e verifique as configurações.
AppNameApplication.kt
@HiltAndroidApp
class AppNameApplication : Application() {
override fun onCreate() {
super.onCreate()
//...
}
}
Essas anotações preparam as classes para receber a injeção de dependência pelo Hilt.
O hilt também é compatível com as seguintes classes:
Activity, Fragment, View, Service e BroadcastReceiver.
.Injetar dependências via hilt numa classe que não é compatível demanda um trabalho a mais.. talvez um próximo artigo. Mas o nosso foco aqui é a classe Worker
então vamos lá.
AppModule.kt
@InstallIn(SingletonComponent::class)
@Module
object AppModule {
@Singleton
@Provides
fun provideUser(): User{
return User("John Doe", 32)
}
}
Agora podemos injetar a instancia de User. Reparem nas anotações elas são importantes para entender os detalhes consultem a documentação do Hilt
hilt-android
@HiltWorker
class SomeWork @AssistedInject constructor(
@Assisted appContext: Context,
@Assisted workerParams: WorkerParameters,
val user: User):
Worker(appContext, workerParams) {
override fun doWork(): Result {
print(user.toString())
return Result.success()
}
}
Agora já estamos usando a instancia de User que vem via injeção do Hilt na classe SomeWork
mas ainda precisamos fazer mais algumas coisas para tudo funcionar. O sistema cria uma instancia de WorkManager
com uma configuração padrão, precisamos criar uma nova configuração para tudo funcionar corretamente.
AndroidManifest.xml
<!--Dentro da Tag application-->
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove" />
Feito isso vamos criar a configuração customizada.
AppNameApplication.kt
@HiltAndroidApp
class AppNameApplication : Application() {
@Inject lateinit var workerFactory: HiltWorkerFactory
override fun getWorkManagerConfiguration(): Configuration {
return Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}
}
Agora sim está tudo pronto para funcionar, você tem uma classe Worker funcionando com injeção de dependências utilizando o Hilt. Parece muito trabalho mas num projeto onde temos vários workers facilita muito o desenvolvimento, Podemos injetar nosso Repository por exemplo e ainda tem a facilidade nos testes.
Até o momento as bibliotecas do Hilt não estavam funcionando bem com a biblioteca do kotlin versão 1.5.20 então usem á versão 1.5.10 que não gerou problemas.
38