This files have been created in 2017 when Google introduced for the first time Android Jetpack Workers.
This implementation show how to use Dagger with Workers
The above usage might been deprecated since now we have Hilt
This files have been created in 2017 when Google introduced for the first time Android Jetpack Workers.
This implementation show how to use Dagger with Workers
The above usage might been deprecated since now we have Hilt
public class AndroidWorkerInjection { | |
public static void inject(Worker worker) { | |
checkNotNull(worker, "worker"); | |
Object application = worker.getApplicationContext(); | |
if (!(application instanceof HasWorkerInjector)) { | |
throw new RuntimeException( | |
String.format( | |
"%s does not implement %s", | |
application.getClass().getCanonicalName(), | |
HasWorkerInjector.class.getCanonicalName())); | |
} | |
AndroidInjector<Worker> workerInjector = | |
((HasWorkerInjector) application).workerInjector(); | |
checkNotNull(workerInjector, "%s.workerInjector() returned null", application.getClass()); | |
workerInjector.inject(worker); | |
} | |
} |
@Module | |
public abstract class AndroidWorkerInjectionModule { | |
@Multibinds | |
abstract Map<Class<? extends Worker>, AndroidInjector.Factory<? extends Worker>> | |
workerInjectorFactories(); | |
} |
@Singleton | |
@Component(modules = { | |
AndroidSupportInjectionModule.class, | |
AndroidWorkerInjectionModule.class, | |
WorkerModule.class}) | |
public interface AppComponent { | |
@Component.Builder | |
interface Builder { | |
@BindsInstance | |
Builder application(MyApplication application); | |
AppComponent build(); | |
} | |
void inject(MyApplication app); | |
} |
public interface HasWorkerInjector { | |
AndroidInjector<Worker> workerInjector(); | |
} |
public class MyApplication extends MultiDexApplication implements HasWorkerInjector { | |
@Inject DispatchingAndroidInjector<Worker> workerDispatchingAndroidInjector; | |
public AppComponent appComponent; | |
@Override | |
public void onCreate() { | |
super.onCreate(); | |
MultiDex.install(this); | |
appComponent = DaggerAppComponent | |
.builder() | |
.application(this) | |
.build(); | |
appComponent.inject(this); | |
//Call the Profile Worker | |
OneTimeWorkRequest refreshProfile = | |
new OneTimeWorkRequest.Builder(ProfileWorker.class) | |
.addTag(ConstantsUtils.TAG_OUTPUT) | |
.build(); | |
WorkManager.getInstance().enqueue(refreshProfile); | |
} | |
@Override | |
public AndroidInjector<Activity> activityInjector() { | |
return dispatchingAndroidInjector; | |
} | |
@Override | |
public AndroidInjector<Worker> workerInjector() { | |
return workerDispatchingAndroidInjector; | |
} | |
} |
public class ProfileWorker extends Worker { | |
@Inject | |
SomeClass clazz; | |
@NonNull | |
@Override | |
public WorkerResult doWork() { | |
AndroidWorkerInjection.inject(this); | |
// Do work here : | |
return WorkerResult.SUCCESS; | |
} | |
} |
@Subcomponent | |
public interface ProfileWorkerModule extends AndroidInjector<ProfileWorker> { | |
@Subcomponent.Builder | |
abstract class Builder extends AndroidInjector.Builder<ProfileWorker>{} | |
} |
@Documented | |
@Target({ElementType.METHOD}) | |
@Retention(RetentionPolicy.RUNTIME) | |
@MapKey | |
public @interface WorkerKey { | |
Class<? extends Worker> value(); | |
} |
@Module(subcomponents = { | |
ProfileWorkerModule.class, | |
UploadWorkerModule.class | |
}) | |
public abstract class WorkerModule { | |
@Binds | |
@IntoMap | |
@WorkerKey(ProfileWorker.class) | |
abstract AndroidInjector.Factory<? extends Worker> bindProfileWorkerFactory(ProfileWorkerModule.Builder profileWorker); | |
} |
@ThePredators
Thanks for the above. Mighty help.
Not sure what I am missing but I get the below stacktrace
2019-12-17 14:08:15.007 28634-28652/com.exsolv.eform E/WM-WorkerWrapper: Work [ id=dca5c889-881e-498d-81ff-f90d8e2af3f9, tags={ com.exsolv.eform.data.remote.services.UploadWorker } ] failed because it threw an exception/error
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: No injector factory bound for Class<com.exsolv.eform.data.remote.services.UploadWorker>
at androidx.work.impl.utils.futures.AbstractFuture.getDoneValue(AbstractFuture.java:516)
at androidx.work.impl.utils.futures.AbstractFuture.get(AbstractFuture.java:475)
at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:284)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.IllegalArgumentException: No injector factory bound for Class<com.exsolv.eform.data.remote.services.UploadWorker>
at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:136)
at com.exsolv.eform.factory.AndroidWorkerInjection.inject(AndroidWorkerInjection.java:26)
at com.exsolv.eform.data.remote.services.UploadWorker.doWork(UploadWorker.java:43)
at androidx.work.Worker$1.run(Worker.java:85)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
can u show how u used class UploadWorker ? Ty.
for people that use Kotlin i advice to stop using dagger and go for this light weight plugin
--> Koin
To Know how to use Koin i made a simple tutorial for every purpose in here :
--> Koin Tutos
I guess this is now deprecated and you should use Hilt Worker Injection
@cbeyls : you can still use this. Dagger is a Java library that has been used on Android. Now they made a much simpler way to do DI using Hilt.
But personally I like Koin much more!!
Can you update this guide with testing configuration?