WorkManager utilizes a Worker class, and WorkManager automatically invokes the Worker.doWork() method in a background thread. Worker.doWork() is a synchronous call. it is expected that you perform and complete all your background work in a blocking manner until the method exits. Since WorkManager operates independently of the activity in the background, the dependency to be injected cannot be directly injected with Hilt’s “@Inject”. We need to provide the dependencies we will inject.

In this blog post, we will use Hilt’s work dependency. Firstly, add the dependency in your build.gradle (app level) file:

implementation("androidx.hilt:hilt-work:1.0.0")


At present, we wish to utilize the DataManager class within our WorkerManager and would like to incorporate it through dependency injection.

@Module
@InstallIn(SingletonComponent::class)
class AppModule {
    @Provides
    @Singleton
    fun provideSharedPreferences(@ApplicationContext context: Context) : SharedPreferences {
        return context.getSharedPreferences("saved_data_preferences", Context.MODE_PRIVATE)
    }

    @Provides
    @Singleton
    fun provideDataManager(sharedPreferences: SharedPreferences) : DataManager {
        return Data(sharedPreferences)
    }
}
class DataManager @Inject constructor(private val sharedPreferences: SharedPreferences) {
    val SAVED_DATA = "SAVED_DATA"
    
    fun saveData(data: String) {
        val editor = sharedPreferences.edit()
        editor.putString(SAVED_DATA, data)
        editor.apply()
    }
    
    fun getData(): String {
        return sharedPreferences.getString(SAVED_DATA, "") ?: ""
    }
}


Currently, our objective is to utilize the DataManager class within our WorkerManager, and we intend to inject it therein. In order to inject our dependency on worker we will use “@AssistedInject” anatation.

“@AssistedInject” is used to annotate the constructor of an object and @Assisted is used to annotate any parameters that need to be provided at runtime. This is particularly useful when you have some dependencies that can be provided by Hilt’s dependency injection and others that are only available at runtime.

@HiltWorker
class DataSavingWorker @AssistedInject constructor(
@Assisted dataManager: DataManager,
@Assisted workerParams: WorkerParameters
) : Worker(workerParams) {
    override fun doWork(): Result {
        try {
            dataManager.saveData("123456")
            return Result.success()

        } catch (e: Exception) {
            return Result.failure()
        }
    }
  }
}


And then we should provide this dependency manually in HiltApplication class.

@HiltAndroidApp
class HiltApplication : Application(), Configuration.Provider {
    @Inject
    lateinit var customWorkerFactory: CustomWorkerFactory
    
    override fun getWorkManagerConfiguration(): Configuration {
        return Configuration.Builder()
            .setMinimumLoggingLevel(Log.DEBUG)
            .setWorkerFactory(customWorkerFactory)
            .build()
    }
}

class CustomWorkerFactory @Inject constructor(private val dataManager: DataManager) : WorkerFactory() {
    override fun createWorker(
        appContext: Context,
        workerClassName: String,
        workerParameters: WorkerParameters
    ): ListenableWorker = DataSavingWorker(dataManager = DataManager, workerParams = workerParameters)
}


Ultimately, you should add the provider to your AndroidManifest.xml file within the <application> tag

   <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            tools:node="remove"/>