I am trying to use work manager with custom delegating factory to create worker with custom parameters. But I keep getting this exception:
Could not instantiate doddlecore.orders.workmanager.OrdersSyncWorker
java.lang.NoSuchMethodException: doddlecore.orders.workmanager.OrdersSyncWorker.<init> [class android.content.Context, class androidx.work.WorkerParameters]
at java.lang.Class.getConstructor0(Class.java:2363)
at java.lang.Class.getDeclaredConstructor(Class.java:2201)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:95)
at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:243)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:145)
at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)
Here is my code:
Android Manifest:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
android:multiprocess="true"
tools:node="merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.work.impl.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
Application:
@Override
public androidx.work.Configuration getWorkManagerConfiguration() {
DelegatingWorkerFactory factory = new DelegatingWorkerFactory();
factory.addFactory(new MyWorkerFactory(orderRepository));
return new androidx.work.Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.INFO)
.setWorkerFactory(factory)
.build();
}
Worker:
class OrdersSyncWorker(
ctx: Context,
params: WorkerParameters,
private val ordersRepo: IOrderRepository
): CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result {
return try {
ordersRepo.syncOrders()
Result.success()
} catch (ex: IllegalStateException) {
Result.retry()
}
}
}
WorkerFactory:
class MyWorkerFactory(private val orderRepository: IOrderRepository) : WorkerFactory() {
override fun createWorker(
appContext: Context,
workerClassName: String,
workerParameters: WorkerParameters
): ListenableWorker? {
return when(workerClassName) {
OrdersSyncWorker::class.java.name ->
OrdersSyncWorker(appContext, workerParameters, orderRepository)
else ->
// Return null, so that the base class can delegate to the default WorkerFactory.
null
}
}
}
I have tried solutions from sources : link. But nothing worked. Not sure what I am missing i'm doing wrong
PS: If I remove the custom parameter and just use
class OrdersSyncWorker(
ctx: Context,
params: WorkerParameters
): CoroutineWorker(ctx, params) {
It runs with no exception. So it is not working when I am adding an extra parameter
Replacing
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
android:multiprocess="true"
tools:node="merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.work.impl.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
to this:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
fixed the issue