web-dev-qa-db-fra.com

Android Work Manager: "Impossible d'instancier Worker"

J'ai suivi le tutoriel Android Developer's sur l'utilisation de la structure Worker Manager pour exécuter mon code en arrière-plan, mais chaque fois que j'essaie de mettre mon travailleur en file d'attente, il ne s'exécute pas et j'obtiens l'erreur suivante:

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

J'ai vu que ce problème pourrait être lié au constructeur par défaut sur le travailleur, mais j'utilise déjà le bon au lieu de la fonction par défaut obsolète.

Mon travailleur est déclaré comme:

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
    }
}

Et il est mis en file d'attente comme suit:

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);
}

Je ne vois rien de différent des exemples, donc j'aimerais comprendre ce qui pourrait affecter mon code et provoquer ce crash. Serait-ce quelque chose de lié à ProGuard?

Ma version est 1.0.0-alpha09

Merci!

12
icarovirtual

Il s'agit d'un problème conn avec WorkManager 1.0.0-alpha09 qui est déjà marqué comme corrigé pour alpha10.

Pour contourner ce problème, vous pouvez ajouter les lignes suivantes à votre configuration proguard:

-keepclassmembers class * extends androidx.work.Worker {
    public <init>(Android.content.Context,androidx.work.WorkerParameters);
}
16
ianhanniballake

J'ai eu le même problème. La cause du problème pour moi était que ma classe Worker était une classe imbriquée. Au moment où j'en ai fait un cours indépendant, ça a marché.

6
Tony

J'ai eu ce problème dans la version stable 1.0.0 et je l'ai résolu en rendant ma classe de travail publique.

class MyWorker extends Worker {...} > public class MyWorker extends Worker {...}
4
Michalsx

Le problème pour moi était le constructeur de ma classe de kotlin:

FAUX

class MyWorker(val app: Application, workerParams: WorkerParameters): Worker(app, workerParams)

BIEN

class MyWorker(val context: Context, workerParams: WorkerParameters): Worker(context, workerParams)
2
Brian