WorkManagerInitializer
requires to configure setWorkerFactory to inject dependencies to the Worker
class. The [document][1] explains about workManager Initialization at AppStartup, but does not provide any insights on how to configure setWorkerFactory. If any could suggest any solutions or workaround, that'll be greatly helpful.
The problem is that I am unable to inject my own dependencies into the workerClass. I have include two scenarios below to explain the case:`
Working Scenario #1:
// This call works fine.
class AppWorker @WorkerInject constructor(
@Assisted context: Context,
@Assisted workerParams: WorkerParameters
) : Worker(context, workerParams) {
companion object {
val workType = "WorkType"
}
override fun doWork(): Result {
return Result.success()
}
}
Failed Scenario #2:
// Initializes WorkManager.
class WorkManagerInitializer : Initializer<WorkManager> {
override fun create(context: Context): WorkManager {
// How to get workFactory required for configuration.
var workerFactory: HiltWorkerFactory? = null
val configuration = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
WorkManager.initialize(context, configuration)
return WorkManager.getInstance(context)
}
override fun dependencies(): List<Class<out Initializer<*>>> {
// No dependencies on other libraries.
return emptyList()
}
}
@HiltAndroidApp
class BaseApp: Application(),Configuration.Provider{
@Inject lateinit var workerFactory: HiltWorkerFactory
override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
init {
Thread.setDefaultUncaughtExceptionHandler(ThreadExceptionalHandler())
}
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
Timber.plant(DebugTree())
}
}
}
Manifest.xml
<?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="com.example.baseapp">
<application
android:name="com.example.baseapp.startup.BaseApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApp"
>
<activity android:name="com.example.baseapp.gui.activities.MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data android:name="com.example.baseapp.startup.AppServicesInitializer"
android:value="androidx.startup" />
</provider>
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
tools:node="remove"/>
</application>
</manifest>
// App complies and runs successfully, but fails to call doWork()
[1]: https://developer.android.com/topic/libraries/app-startup
The AppWorker class dowork() method is not getting called with WorkManagerInitializer defined at AppStartup. Here is the error in logcat:
2020-09-24 19:38:41.811 23803-23863/com.example.baseapp E/WM-WorkerFactory: Could not instantiate com.example.baselib.services.local.work_manager.worker.AppWorker
java.lang.NoSuchMethodException: com.example.baselib.services.local.work_manager.worker.AppWorker.<init> [class android.content.Context, class androidx.work.WorkerParameters]
at java.lang.Class.getConstructor0(Class.java:2332)
at java.lang.Class.getDeclaredConstructor(Class.java:2170)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:95)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:242)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:136)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)