Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Work Manager: "Could not instantiate Worker"

I've followed the Android Developer's tutorial on using the Worker Manager structure to run my code in background but anytime I try to enqueue my worker it doesn't run and I get the following error:

2018-10-04 22:25:47.004 28669-28885/app.package.com.debug E/DefaultWorkerFactory: Could not instantiate app.package.com.MyWorker
    java.lang.NoSuchMethodException: <init> []
        at java.lang.Class.getConstructor0(Class.java:2320)
        at java.lang.Class.getDeclaredConstructor(Class.java:2166)
        at androidx.work.DefaultWorkerFactory.createWorker(DefaultWorkerFactory.java:58)
        at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:180)
        at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:117)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)
2018-10-04 22:25:47.005 28669-28885/app.package.com.debug E/WorkerWrapper: Could for create Worker app.package.com.MyWorker

I've seen that this problem could be related to the default constructor on the worker but I already use the correct one instead of the deprecated default function.

My worker is declared as:

public class MyWorker extends Worker {

    public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        // Doesn't even get called
    }
}

And it gets queued like so:

WorkManager workManager = WorkManager.getInstance();
if (myWorkerRequest == null) {
    myWorkerRequest = new OneTimeWorkRequest.Builder(MyWorker.class)
            .setConstraints(new Constraints.Builder()
                    .setRequiredNetworkType(NetworkType.CONNECTED)
                    .build())
            .build();
}
WorkStatus workStatus = workManager.getStatusById(myWorkerRequest.getId()).getValue();
if (workStatus == null || !workStatus.getState().isFinished()) {
    workManager.enqueue(myWorkerRequest);
}

I'm not seeing anything different from the examples so I'd like to understand what else could affect my code to cause this crash. Could it be something ProGuard related?

My version is 1.0.0-alpha09

Thanks!

like image 442
Ícaro Avatar asked Oct 05 '18 01:10

Ícaro


2 Answers

I had the same issue. The cause of the issue for me was that my Worker class was a nested class. The moment I made it an independent class, it worked.

like image 72
Tony Avatar answered Oct 14 '22 01:10

Tony


This is a known issue with WorkManager 1.0.0-alpha09 that is already marked as fixed for alpha10.

As a workaround, you can add the following lines to your proguard configuration:

-keepclassmembers class * extends androidx.work.Worker {
    public <init>(android.content.Context,androidx.work.WorkerParameters);
}
like image 41
ianhanniballake Avatar answered Oct 14 '22 01:10

ianhanniballake