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
<?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