Skip to content

Instantly share code, notes, and snippets.

@ferrerojosh
Created May 30, 2018 06:40
Show Gist options
  • Save ferrerojosh/82bd92748f315155fa6a842f4ed64c82 to your computer and use it in GitHub Desktop.
Save ferrerojosh/82bd92748f315155fa6a842f4ed64c82 to your computer and use it in GitHub Desktop.
androidx workmanager injector temporary impl
import androidx.work.Worker
object AndroidWorkerInjection {
fun inject(worker: Worker) {
checkNotNull(worker, { "worker" })
val application = worker.applicationContext
if (application !is HasWorkerInjector) {
throw RuntimeException("${application.javaClass.canonicalName} does not implement ${HasWorkerInjector::class.java.canonicalName}")
}
val workerInjector = (application as HasWorkerInjector).workerInjector()
checkNotNull(workerInjector, { "${application.javaClass}.workerInjector() return null" })
workerInjector.inject(worker)
}
}
import androidx.work.Worker
import dagger.Module
import dagger.android.AndroidInjector
import dagger.multibindings.Multibinds
@Module
abstract class AndroidWorkerInjectionModule {
@Multibinds
abstract fun workerInjectorFactories(): Map<Class<out Worker>, AndroidInjector.Factory<out Worker>>
}
import dagger.Component
import dagger.android.AndroidInjectionModule
import dagger.android.AndroidInjector
import javax.inject.Singleton
@Singleton
@Component(modules = [
// AppModule::class,
// AndroidInjectionModule::class
// And all other related modules
AndroidWorkerInjectionModule::class
])
interface AppComponent : AndroidInjector<App> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<App>()
}
import androidx.work.Worker
import dagger.android.AndroidInjector
interface HasWorkerInjector {
fun workerInjector(): AndroidInjector<Worker>
}
import androidx.work.Worker
import javax.inject.Inject
class MyWorker : Worker() {
override fun doWork(): WorkerResult {
AndroidWorkerInjection.inject(this)
return WorkerResult.SUCCESS
}
}
import dagger.Subcomponent
import dagger.android.AndroidInjector
@Subcomponent
interface MyWorkerSubcomponent : AndroidInjector<MyWorker> {
@Subcomponent.Builder
abstract class Builder : AndroidInjector.Builder<MyWorker>()
}
import androidx.work.Worker
import dagger.MapKey
import kotlin.reflect.KClass
@MapKey
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class WorkerKey(val value: KClass<out Worker>)
import dagger.Binds
import dagger.Module
import dagger.android.AndroidInjector
import dagger.multibindings.IntoMap
@Module(subcomponents = [
MyWorkerSubcomponent::class
])
abstract class WorkerModule {
@Binds
@IntoMap
@WorkerKey(MyWorker::class)
abstract fun bindMyWorkerFactory(builder: MyWorkerSubcomponent.Builder): AndroidInjector.Factory<out Worker>
}
@Abhityagi16
Copy link

@Iamsdt I'm getting the same error. Have you found a fix for it?

@wellingtoncosta
Copy link

Hi,

I'm getting the error:

error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.String,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends androidx.work.Worker>>> cannot be provided without an @Provides-annotated method.

@arekolek (or anyone else) did you get this error?

@nkontizas
Copy link

Hi,

I'm getting the same error with @wellingtoncosta. The error started after I upgraded dagger 2.16 -> 2.17. Also for workmanager I have version 1.0.0-alpha09.

@pedrovarela86
Copy link

pedrovarela86 commented Sep 26, 2018

Hello everybody , this implementation was working beautiful, until las week. Googlers updated the library andWork() is deprecated , now it needs Context and WorkParameters I have been trying to solve the issue myself, but there are plenty of thing I don't quite understand. Any idea on how to update this code?

@nkontizas
Copy link

Hi,

For the error of @wellingtoncosta and mine I found a solution. The dagger framework at DispatchingAndroidInjector takes 2 Maps at the constructor. All I needed to do was to add the extra binding:

@Module
abstract class AndroidWorkerInjectionModule {

    @Multibinds
    @Suppress(names = ["UNUSED"])
    abstract fun workerInjectorFactories(): Map<Class<out Worker>, AndroidInjector.Factory<out Worker>>

    /* New binding */
    @Multibinds
    @Suppress(names = ["UNUSED"])
    abstract fun workerStringInjectorFactories(): Map<String, AndroidInjector.Factory<out Worker>>
}

@ferrerojosh
Copy link
Author

Since the update from Work Manager and Dagger broke some things, please use this gist @luanmm made instead: https://gist.github.com/luanmm/85dd8217ed3f7384e6bab075a8ab7a61

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment