web-dev-qa-db-fra.com

Android WorkManager api pour l'exécution de tâches quotidiennes en arrière-plan

Je dois appeler une API par jour en arrière-plan, même si l'application est fermée. J'ai vu à propos de l'API WorkManager. Pour mon scénario, j'ai essayé PeriodicWorkRequest, mais malheureusement, cela ne fonctionne pas comme prévu. Ce que j'ai fait est que j'ai utilisé ce code dans la classe Application 

 PeriodicWorkRequest.Builder myWorkBuilder =
                new PeriodicWorkRequest.Builder(MyWorker.class, 24,
                        TimeUnit.HOURS);

        PeriodicWorkRequest myWork = myWorkBuilder.build();
        WorkManager.getInstance().enqueue(myWork);

Mais il est exécuté à plusieurs reprises 11 fois lorsque l'application est ouverte pour la première fois, après 24 heures. S'il vous plaît, aidez-moi à résoudre.

13
lavanya velu

Si vous voulez vous assurer que votre PeriodicWorkRequest n'est pas créé plusieurs fois, vous pouvez utiliser la méthode WorkManager.enqueueUniquePeriodicWork pour planifier votre ouvrier:

Cette méthode vous permet de mettre en file d'attente un PeriodicWorkRequest au nom unique, dans lequel un seul PeriodicWorkRequest d'un nom particulier peut être actif à la fois. Par exemple, vous souhaiterez peut-être qu'une seule opération de synchronisation soit active. S'il en reste un, vous pouvez le laisser s'exécuter ou le remplacer par votre nouveau travail.


Par exemple:

PeriodicWorkRequest.Builder myWorkBuilder =
            new PeriodicWorkRequest.Builder(MyWorker.class, 24, TimeUnit.HOURS);

PeriodicWorkRequest myWork = myWorkBuilder.build();
WorkManager.getInstance()
    .enqueueUniquePeriodicWork("jobTag", ExistingPeriodicWorkPolicy.KEEP, myWork);
19
whlk

Je pense qu'il y a trois problèmes.

1) Vous créez un nouveau travail périodique chaque fois que vous enqueuemyWork dans l’instance WorkManager.

Essayez-le, la logique de la méthode doWork() de votre MyWorker.class s'exécute une fois, une fois, et deux fois. Vous avez probablement ajouté 11 œuvres à Work Manager, raison pour laquelle il a été exécuté 11 fois, la dernière fois que vous avez vérifié. Si vous créez de nouvelles œuvres et que vous les ajoutez au gestionnaire de travaux, le nombre d'exécutions de myWork augmente.

Semblable à Job Scheduler, vous devez vérifier si le travail existe ou non avant de l'ajouter à Work Manager.

Exemple de code:

final WorkManager workManager = WorkManager.getInstance();
final LiveData<List<WorkStatus>> statusesByTag = workManager
        .getStatusesByTag(TAG_PERIODIC_WORK_REQUEST);

    statusesByTag.observe(this, workStatuses -> {
    if (workStatuses == null || workStatuses.size() == 0) {
        Log.d(TAG, "Queuing the Periodic Work");
        // Create a periodic request
        final PeriodicWorkRequest periodicWorkRequest =
                new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES)
                        .addTag(TAG_PERIODIC_WORK_REQUEST)
                        .build();

        // Queue the work
        workManager.enqueue(periodicWorkRequest);
    } else {
        Log.d(TAG, "Work Status Size: " + workStatuses.size());
        for (int i = 0; i < workStatuses.size(); i++) {
            Log.d(TAG, "Work Status Id: " + workStatuses.get(i).getId());
            Log.d(TAG, "Work Status State: " + workStatuses.get(i).getState());
        }
        Log.d(TAG, "Periodic Work already exists");
    }
});

Dans l'exemple ci-dessus, j'utilise une balise unique TAG_PERIODIC_WORK_REQUEST pour identifier mon travail périodique et vérifier s'il existe ou non avant de le créer.

2) Votre travail peut ne pas être en cours lorsque l'application est tuée.

Quelle est la marque sur laquelle vous testez? Est-ce Xiaomi? Avez-vous testé sur plusieurs autres marques et abouti au même résultat?

Était-ce en mode Doze? Et comment confirmez-vous que le travail ne fonctionne pas lorsque vous définissez un délai de 24 heures?

Work Manager offre une compatibilité ascendante, mais vous devez tout de même gérer la logique propre à l'appareil. Sur les périphériques Xiaomi, similaires au planificateur de tâches (ou au répartiteur de tâches Firebase ou à l’alarme), le travail périodique s’arrête lorsque l’application est supprimée.

3) Je pense juste que la PeriodicWorkRequest fournie par WorkManager est un buggy.

Je le teste depuis le début de la semaine précédente sur plusieurs appareils. J'ai créé une œuvre lorsque l'application a été lancée pour la première fois et je ne l'ai pas ouverte pendant trois jours. Il a été lancé une fois, deux fois lorsque la deuxième synchronisation a été déclenchée et entre-temps, il est passé à 13 fois, puis à une fois, 4 fois, etc.

Dans un autre test, j'ai créé un travail avec le code ci-dessous lors de la première installation et supprimé le code de la deuxième installation. Pendant ce test, même si le travail s'est terminé avec succès, le travail a été exécuté à chaque fois, l'application est ouverte après l'avoir tuée.

final PeriodicWorkRequest periodicWorkRequest =
            new PeriodicWorkRequest.Builder(SyncWorker.class, 30, TimeUnit.MINUTES)
                    .addTag("periodic-work-request")
                    .build();

// Queue the work
WorkManager.getInstance().enqueue(periodicWorkRequest);

Je comprends cela car il est encore en alpha. Je ne pense pas que vous devriez l'utiliser en production.

8
Srikar Reddy

Si vous ajoutez une balise à la PeriodicWorkRequestBuilder, puis appelez WorkManager.getInstance().cancelAllWorkByTag(REQUEST_TAG) avant de mettre la demande périodique en file d'attente, cela évitera les dupes

Android Workmanager PeriodicWorkRequest n'est pas unique

2
Joe H

À partir de alpha03, vous pouvez planifier un travail périodique unique: https://developer.Android.com/jetpack/docs/release-notes

WorkManager.enqueueUniquePeriodicWork (String uniqueWorkName, ExistingPeriodicWorkPolicy existingPeriodicWorkPolicy, PeriodicWorkRequest périodiqueWork) permet de mettre en file d'attente un. PeriodicWorkRequest

Il est donc beaucoup plus simple de réaliser ce que vous voulez maintenant.

1
Gaket

Il y avait un problème dans l'alpha 01 qui:

Correction d'un problème qui entraînait le replanification des travailleurs sur Application.onCreate (). 

Utilisez la dernière version de WorkManager, à savoir 1.0.0-alpha02. Vérifiez Notes de publication pour plus d'informations

0
Sagar

Utilisez la version de WorkManager 1.0.0-alpha04. Vous pouvez consulter les notes de publication ici

Consultez également cette démonstration - PeriodicWorkRequest GitHub qui met à jour le compteur de jours une fois par jour (toutes les 24 heures) pendant la fenêtre de maintenance. Il exécute la méthode doWork (), que l'application soit ouverte ou fermée.

WorkManager est toujours en mode alpha. Il fonctionnera donc complètement pour tous les périphériques une fois la version finale publiée.

0
Viraj Patel