Inject into Workers (androidx.WorkManager API)

Dharma Sai Seerapu
2 min readFeb 12, 2019

--

From latest Google I/O you just presented the new `androidx.work.Worker` class, part of the new [WorkManager API](https://developer.android.com/topic/libraries/architecture/workmanager).

Since the `Worker` class is created by the framework (we only pass the Worker class type to the `WorkManager`), how can we @Inject fields into the Worker?

Let’s see how we @Inject fields into the worker?

Step 1: Create AndroidWorkerInjection.class Responsible for injecting dependencies into [WorkManager API](https://developer.android.com/topic/libraries/architecture/workmanager).

public class AndroidWorkerInjection {

public static void inject(Worker worker) {
//TODO : Check not null

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);
}
}

Step 2: Create a AndroidWorkerInjectionModule.class responsible for the binding same type of classes into one. In our case, all the class extends Worker class

@Module
public abstract class AndroidWorkerInjectionModule {

@Multibinds
abstract Map<Class<? extends Worker>, AndroidInjector.Factory<? extends Worker>>
workerInjectorFactories();
}

Step 3: Let's define our AppComponent.class and add above modules into it as below

@Singleton
@Component(modules = {
AppModule.class,
AndroidInjectionModule.class,
AndroidWorkerInjectionModule.class, // Worker injection module referenced in the AppComponent
WorkerModule.class}) // Worker Module
public interface AppComponent {

@Component.Builder
interface Builder {

@BindsInstance
Builder application(Application application);

AppComponent build();
}

void inject(MyApplication myApplication);
}

Step 4: Define HasWorkerInjector as how we usually define Injectors for Activities HasActivityInjector, Services HasServiceInjector and etc..

public interface HasWorkerInjector {
AndroidInjector<Worker> workerInjector();
}

Step 5: let's implement HasWorkerInjector in the Application class. In our case Application is: MyApplication.class

public class MyApplication extends Application implements HasWorkerInjector{

@Inject
DispatchingAndroidInjector<Worker> workerDispatchingAndroidInjector;

private AppComponent appComponent;

@Override
public void onCreate() {
super.onCreate();

initializeDaggerComponent();
}

@Override
public AndroidInjector<Worker> workerInjector() {
return workerDispatchingAndroidInjector;
}

private void initializeDaggerComponent() {

appComponent = DaggerAppComponent.builder().application(this).build();
appComponent.inject(this);
}
}

Step 6: Let’s define our WorkerModule class and each individual modules into it.

@Module(subcomponents = {
ProfileWorkerModule.class
})
public abstract class WorkerModule {
@Binds
@IntoMap
@WorkerKey(ProfileWorker.class) //Define your Worker class extends Worker class
abstract AndroidInjector.Factory<? extends Worker> bindProfileWorkerFactory(WorkerComponent.Builder profileWorker);
}

Step 7: Create the corresponding Module i.e., ProfileWorkerModule.class

@Subcomponent
public interface ProfileWorkerModule extends AndroidInjector<ProfileWorker> {

@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<CustomWorkManager>{}
}

Step 8: Let's create ProfileWorker.class and inject the dependencies. As simple as that.

public class ProfileWorker extends Worker {

public static final String MODEL_OBJECT = "sync_model";

@Inject
SomeClass someClass; // Dependency is injected here

public ProfileWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}

@NonNull
@Override
public Result doWork() {

AndroidWorkerInjection.inject(this);// Injecting worker class here.
return Result.Success.success();
}
}

--

--

Dharma Sai Seerapu

IoT & Startup Enthusiast. Android, Kotlin, SOLID/Clean code, Clean Architecture. Stack-Overflowing, Blogger, Learning, Sharing & other cool stuff