androidandroid-workmanager

Android WorkManager Exception: Could not create Worker


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


Solution

  • 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