Skip to content

Instantly share code, notes, and snippets.

@gbzarelli
Last active March 2, 2022 07:21
Show Gist options
  • Save gbzarelli/5012ecd63268e26d8ef63c36ed2ee643 to your computer and use it in GitHub Desktop.
Save gbzarelli/5012ecd63268e26d8ef63c36ed2ee643 to your computer and use it in GitHub Desktop.
Dagger with Worker

Dagger with Worker

Exemplo de classes para realizar injeção de dependências com Dagger em seus Workers.

Example classes to perform injection dependencies with Dagger on your Workers.

Project

Sources and thanks

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" package="br.com.helpdev.githubers">
<application>
[...]
<!--
Incluir o provider para autorizar o WorkManager subistituir o Factory
Include the provider to authorize the WorkManager to replace Factory
-->
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:exported="false"
tools:node="remove"/>
</application>
</manifest>
package br.com.helpdev.githubers.di
import android.app.Application
import android.content.Context
import br.com.helpdev.githubers.GithubersApp
import br.com.helpdev.githubers.di.module.ActivitiesModule
import br.com.helpdev.githubers.di.module.AppModule
import br.com.helpdev.githubers.di.module.WorkersModule
import br.com.helpdev.githubers.di.worker.WorkerInjectorFactory
import dagger.BindsInstance
import dagger.Component
import dagger.android.AndroidInjectionModule
import javax.inject.Singleton
@Suppress("unused")
@Singleton
@Component(
modules = [
AndroidInjectionModule::class,
AppModule::class,// <-- Your modules
WorkersModule::class // <-- Worker module
/* ADD YOUR MODULES HERE */
]
)
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
fun inject(githubApp: GithubersApp)
}
package br.com.helpdev.githubers
import android.app.Activity
import android.app.Application
import androidx.work.Configuration
import androidx.work.WorkManager
import br.com.helpdev.githubers.di.AppInjector
import br.com.helpdev.githubers.di.worker.WorkerInjectorFactory
import dagger.android.DispatchingAndroidInjector
import dagger.android.HasActivityInjector
import javax.inject.Inject
/**
* Full sample with Android activities injection:
* -> https://github.com/helpdeveloper/githubers/blob/master/app/src/main/java/br/com/helpdev/githubers/GithubersApp.kt
*/
class GithubersApp : Application(){
/**
* Injeta o WorkerInjectorFactory para configurar o WorkManager
* Inject the WorkerInjectorFactory to configure WorkManager
*/
@Inject
lateinit var workerInjectorFactory: WorkerInjectorFactory
override fun onCreate() {
super.onCreate()
// ----------------
DaggerAppComponent.builder().application(githubApp)
.build().inject(githubApp)
// ----------------
configureWorkerWithDagger()
}
private fun configureWorkerWithDagger() {
val config = Configuration.Builder()
.setWorkerFactory(workerInjectorFactory)
.build()
WorkManager.initialize(this, config)
}
}
package br.com.helpdev.githubers.worker
import android.content.Context
import android.util.Log
import androidx.work.Worker
import androidx.work.WorkerParameters
import br.com.helpdev.githubers.data.repository.GithubUserRepository
import br.com.helpdev.githubers.di.worker.IWorkerFactory
import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import javax.inject.Inject
import javax.inject.Provider
class GithubUsersWorker(
context: Context, workerParams: WorkerParameters,
private val userRepository: GithubUserRepository
) : Worker(context, workerParams) {
override fun doWork(): Result {
//TODO
return Result.success()
}
/**
* Factory responsável em criar o Worker com DI.
* Factory responsible for creating Worker with DI.
*/
class Factory @Inject constructor(
private val userRepository: Provider<GithubUserRepository> // <-- Add your providers parameters
) : IWorkerFactory<GithubUsersWorker> {
override fun create(appContext: Context, params: WorkerParameters): GithubUsersWorker {
return GithubUsersWorker(appContext, params, userRepository.get())
}
}
}
package br.com.helpdev.githubers.di.worker
import androidx.work.ListenableWorker
import androidx.work.WorkerParameters
/**
* Interface para criar os Factory de cada Worker.
* Interface to creates Factory of each Worker.
*
* Sample to use:
* class MyWorker(context,workerParameter,...): Worker(context,workerParameters){
* [...]
* class MyWorkerFactory([injectable parameters]):IWorkerFactory{
* //create worker
* }
* }
*/
interface IWorkerFactory<T : ListenableWorker> {
fun create(appContext:Context, params: WorkerParameters): T
}
package br.com.helpdev.githubers.di.worker
import android.content.Context
import androidx.work.ListenableWorker
import androidx.work.WorkerFactory
import androidx.work.WorkerParameters
import javax.inject.Inject
import javax.inject.Provider
/**
* O WorkerInjectorFactory é responsável por instanciar o {@link IWorkerFactory} do Worker.
* Ele injeta as dependências dentro do {@link IWorkerFactory} que gera o Worker
*
* Obs: Lembre-se de mapear seu Worker em um modulo com o {@link WorkerKey}.
*
* The WorkerInjectorFactory is responsible to instancing the {@link IWorkerFactory} of the Worker.
* It inject the dependencies into the {@link IWorkerFactory} that create the Worker.
*
* Note: Remember to map your Worker into a module with the {@link WorkerKey}.
*/
class WorkerInjectorFactory @Inject constructor(
private val workerFactoryMap: Map<Class<out ListenableWorker>, @JvmSuppressWildcards Provider<IWorkerFactory<out ListenableWorker>>>
) : WorkerFactory() {
override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters)
: ListenableWorker? {
val entry = workerFactoryMap.entries.find { Class.forName(workerClassName).isAssignableFrom(it.key) }
val factory = entry?.value ?: throw IllegalArgumentException("could not find worker: $workerClassName")
return factory.get().create(appContext, workerParameters)
}
}
package br.com.helpdev.githubers.di.worker
import androidx.work.ListenableWorker
import dagger.MapKey
import kotlin.reflect.KClass
/**
* Cria a notação de um MapKey para mapear os Workers com DI
* Create a MapKey annotation to map Workers with DI
*/
@MapKey
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class WorkerKey(val value: KClass<out ListenableWorker>)
package br.com.helpdev.githubers.di.module
import androidx.work.ListenableWorker
import br.com.helpdev.githubers.di.worker.IWorkerFactory
import br.com.helpdev.githubers.di.worker.WorkerKey
import br.com.helpdev.githubers.worker.GithubUsersWorker
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap
/**
* Modulo para registrar os Workers
* Modulo to the Workers register
*/
@Suppress("unused")
@Module
interface WorkersModule {
/**********************************************
* ADICIONAR OS WORKERS QUE UTILIZAM DI AQUI!
* ADD THE WORKERS WITH DI USAGE HERE!
*********************************************/
@Binds
@IntoMap
@WorkerKey(GithubUsersWorker::class)
fun bindGithubUsersWorker(worker: GithubUsersWorker.Factory): IWorkerFactory<out ListenableWorker>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment