web-dev-qa-db-fra.com

Quels outils sont disponibles pour tester JobScheduler?

Nous implémentons un Job via JobScheduler pour le chargement en arrière-plan des données. Le travail sera déclenché environ une fois par jour. Quels outils sont disponibles pour tester cette fonctionnalité (éventuellement ADB)?

Les cas d'utilisation doivent permettre de simuler les conditions requises pour l'exécution d'un travail ou simplement de dire spécifiquement "Exécuter ce travail" dans le cadre de notre suite de tests automatisés.

49
greg7gkb

Droite.
Henning et P4u144 m’ont mis sur la bonne voie pour répondre plus en détail à cette question.

Identifier tous les emplois enregistrés

Identifiez votre tâche avec le adb Shell dumpsys jobscheduler commande.
Cela vous donnera une sortie énorme dans les catégories suivantes.

  • Paramètres
  • Enregistré XX emplois
  • Connectivité
  • Les alarmes
  • Tourner au ralenti
  • Batterie
  • AppIdle
  • Contenu
  • Historique de l'emploi
  • Queue en attente

La catégorie qui vous intéresse le plus est Enregistrement de XX emplois . Cela vous indique combien de tâches ont été planifiées sur le périphérique.
Par exemple, votre nom de fichier est com.foo.bar.application vous devriez voir une entrée comme celle-ci:

JOB #u0a93/17: eec3709 com.foo.bar.application/com.evernote.Android.job.v21.PlatformJobService
    u0a93 tag=*job*/com.foo.bar.application/com.evernote.Android.job.v21.PlatformJobService
    Source: uid=u0a93 user=0 pkg=com.foo.bar.application
    JobInfo:
      Service: com.foo.bar.application/com.evernote.Android.job.v21.PlatformJobService
      PERIODIC: interval=+15m0s0ms flex=+5m0s0ms
      PERSISTED
      Requires: charging=false deviceIdle=false
      Network type: 2
      Backoff: policy=1 initial=+30s0ms
      Has early constraint
      Has late constraint
    Required constraints: TIMING_DELAY DEADLINE UNMETERED
    Satisfied constraints: CONNECTIVITY NOT_ROAMING APP_NOT_IDLE DEVICE_NOT_DOZING
    Unsatisfied constraints: TIMING_DELAY DEADLINE UNMETERED
    Earliest run time: 07:23
    Latest run time: 12:23
    Ready: false (job=false pending=false active=false user=true)

Astuce: Utilisez adb Shell dumpsys jobscheduler | grep com.foo.bar.application pour filtrer rapidement la liste.

Maintenant, vous pouvez facilement identifier si votre travail a été enregistré avec les critères corrects.

FireBaseJobdispatcher

Si vous utilisez FirebaseJobDispatcher lib, vous pouvez utiliser

adb Shell dumpsys activity service GcmService | grep com.foo.bar.debug
    com.foo.bar.debug:0 v853
    u0|com.foo.bar.debug: 3
    (scheduled) com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver{u=0 tag="com.foo.bar.debug.job.FetchArticlesJob" trigger=window{start=10800s,end=11700s,earliest=10448s,latest=11348s} requirements=[NET_UNMETERED,DEVICE_IDLE] attributes=[PERSISTED,RECURRING] scheduled=-351s last_run=N/A jid=N/A status=PENDING retries=0 client_lib=FIREBASE_JOB_DISPATCHER-1}
    (scheduled) com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver{u=0 tag="com.foo.bar.debug.job.FetchNotificationGroupsJob" trigger=window{start=86400s,end=129600s,earliest=86048s,latest=129248s} requirements=[NET_CONNECTED,CHARGING] attributes=[PERSISTED,RECURRING] scheduled=-351s last_run=N/A jid=N/A status=PENDING retries=0 client_lib=FIREBASE_JOB_DISPATCHER-1}
    (scheduled) com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver{u=0 tag="com.foo.bar.debug.job.RemoveUnusedRealmArticlesJob" trigger=window{start=577980s,end=608400s,earliest=521961s,latest=552381s} requirements=[NET_ANY] attributes=[PERSISTED,RECURRING] scheduled=-56018s last_run=N/A jid=N/A status=PENDING retries=0 client_lib=FIREBASE_JOB_DISPATCHER-1}
    (finished) [com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver:com.foo.bar.debug.job.UpdateNotificationGroupJob,u0]
    (finished) [com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver:com.foo.bar.debug.job.UpdatePushTokenJob,u0]
    (finished) [com.foo.bar.debug/com.firebase.jobdispatcher.GooglePlayReceiver:com.foo.bar.debug.job.FetchArticlesJob,u0]

pour vérifier si votre service a été planifié ou exécuté.

Forcer votre tâche à courir

Lorsque vous créez un Job, vous obtenez un JOB_ID revenu.
Utilisez ceci JOB_ID pour forcer l'exécution du travail.
Vous pouvez le faire en utilisant le adb Shell cmd jobscheduler run commande, (nécessite Android 7.1 ou supérieur).

Par exemple, votre nom de fichier est com.foo.bar.application et le JOB_ID était 1. Vous pouvez maintenant exécuter votre tâche via adb

adb Shell cmd jobscheduler run -f com.foo.bar.application 1

N'oubliez pas le -f, car le travail est exécuté même si les restrictions définies ne sont pas respectées.

Evernote Android Librairie)

Dernier point mais non le moindre.
Utilisez la merveilleuse bibliothèque d’Evernote pour cela.
Il permet un portage facile de JobScheduler sur des niveaux d'API inférieurs en utilisant JobScheduler, GcmNetworkManager ou AlarmManager en fonction de votre niveau d'API.

Éditer le 24/08

Mieux encore, utilisez la bibliothèque de répartition des travaux Firebase.

Firebase JobDispatcher est une bibliothèque permettant de planifier des tâches en arrière-plan dans votre Android app. Elle fournit une API compatible avec JobScheduler qui fonctionne sur toutes les versions récentes de Android (API de niveau 9 ou supérieur) sur laquelle les services Google Play sont installés.

J'espère que cela a aidé.

Merci

Modifier le 28/04/2019

Evernote Android-Job et Firebase JobDispatcher sont maintenant en mode de maintenance uniquement et suggèrent tous deux d'utiliser le composant WorkManager de jetpack pour ce type de travail.

93
tim

Avec la commande adb Shell dumpsys jobscheduler vous obtenez des informations sur les tâches actuellement planifiées et actives.

J'ai remarqué que la sortie de la commande diffère grandement entre Android 6 et 7. Avec un appareil Android 5 , la sortie est très court et parfois crypté. La partie intéressante avec les tâches enregistrées est la construction ici et répétée ci-dessous pour des raisons de commodité, ce qui devrait faciliter le déchiffrement:

@Override
public String toString() {
    return String.valueOf(hashCode()).substring(0, 3) + ".."
            + ":[" + job.getService()
            + ",jId=" + job.getId()
            + ",u" + getUserId()
            + ",R=(" + formatRunTime(earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME)
            + "," + formatRunTime(latestRunTimeElapsedMillis, NO_LATEST_RUNTIME) + ")"
            + ",N=" + job.getNetworkType() + ",C=" + job.isRequireCharging()
            + ",I=" + job.isRequireDeviceIdle() + ",F=" + numFailures
            + ",P=" + job.isPersisted()
            + (isReady() ? "(READY)" : "")
            + "]";
}

Les appareils Android 7 , en revanche, ont une très longue sortie avec des informations plus détaillées et mieux lisibles. En outre, il y a plus de fonctionnalités comme une histoire. L'inconvénient est que vous devez d'abord trouver les parties intéressantes.

Je n'ai pas trouvé de moyen de forcer l'exécution d'un travail, il y a une demande de fonctionnalité pour cela. Voir la réponse de p4u144.

16
Henning

À partir de Android 7.0, il y a un nouveau cmd pour adb Shell. Et en 7.1 (uniquement dans l'aperçu pour le moment)), le adb Shell cmd jobscheduler a été ajouté comme vous pouvez le voir ici pour forcer l'exécution de votre JobScheduler. L'aide dit:

Commandes du planificateur de travaux (jobscheduler): help Affiche ce texte d'aide.

run [-f | --force] [-u | --user USER_ID] PACKAGE JOB_ID Déclencher l'exécution immédiate d'un travail planifié spécifique. Options: -f ou --force: exécuter le travail même si les contraintes techniques, telles que la connectivité, ne sont pas encore respectées. -U ou --user: spécifiez le travail de l'utilisateur à exécuter. la valeur par défaut est l'utilisateur principal ou l'utilisateur système

14
p4u144