Search code examples
androiddagger-2android-workmanager

App keeps crashing while initialising Worker with Dagger2 in Android 6.0


java.lang.ClassCastException: androidx.work.impl.workers.ConstraintTrackingWorker cannot be cast to androidx.work.Worker at java.lang.Class.asSubclass(Class.java:1486) at com.mpower.android.lpincrm.workers.DaggerWorkerFactory.createWorker(DaggerWorkerFactory.kt:38) at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:83) 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:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)

Error is occurring on the first line of createWorker():

override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters): ListenableWorker? {
        val workerclass = Class.forName(workerClassName).asSubclass(Worker::class.java)
        val constructor = workerclass.getDeclaredConstructor(Context::class.java, WorkerParameters::class.java)
        val instance = constructor.newInstance(appContext, workerParameters)


    when (instance) {
        is MetaWorker -> {
            instance.treatmentMetaRepository = foo
            instance.newsRepository = foo1
            instance.geoDataRepository = foo2
            instance.medicineMetaRepository = foo3
            instance.preferenceUtil = preferenceUtil
        }
        is NotificationSchedulerWorker -> {
            instance.notificationRepository = notification
        }
        is SyncWorker -> {
            instance.syncAPIs = syncAPI
            instance.registrationAPI = registrationAPI
            instance.preferenceUtil = preferenceUtil
            instance.treatmentRepository = treatmentRepository
            instance.medicineRepository = medicineRepository
            instance.medicineDetailsRepository = medicineDetailsRepository
            instance.collectionRepository = collectionRepository
            instance.newVisitRepository = newVisitRepository
            instance.dueReceiptRepository = dueReceiptRepository
            instance.transportationRepository = transportationRepository  
        }
    }
    return instance
}

My worker version:

def work_version = "2.3.4"
implementation "androidx.work:work-runtime:$work_version"

Solution

  • Your WorkerFactory incorrectly assumes that every ListenableWorker subclass created by the app is also a Worker subclass. It turns out that the WorkManager library contains some exceptions to this rule, which are used as internal implementation details.

    The fix is to treat the passed worker classes as subclasses of ListenableWorker, not Worker.

    val workerclass = Class.forName(workerClassName).asSubclass(ListenableWorker::class.java)