有哪些工具可用于测试JobScheduler?

gre*_*gkb 51 android job-scheduling android-jobscheduler

我们通过JobScheduler实现了一个Job,用于后台加载数据.这项工作每天会开一次.我们可以使用哪些工具来测试此功能(可能是ADB)?

用例是能够模拟运行作业所需的条件,或者只是说"运行此作业"作为我们自动化测试套件的一部分.

tim*_*tim 95

对.
Henning和P4u144让我在正确的轨道上更详细地回答这个问题.

确定所有已注册的职位

使用该adb shell dumpsys jobscheduler命令识别您的任务.
这将为您提供以下类别的巨大输出.

  • 设置
  • 注册XX工作
  • 连接
  • 警报
  • 电池
  • AppIdle
  • 内容
  • 工作经历
  • 待排队

您最有可能感兴趣的类别是注册XX工作.这会告诉您已在设备上安排了多少个作业.
例如,您的包名称com.foo.bar.application应该是这样的条目:

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)
Run Code Online (Sandbox Code Playgroud)

提示:adb shell dumpsys jobscheduler | grep com.foo.bar.application用于快速过滤列表.

现在,您可以轻松识别您的工作是否已使用正确的标准进行注册.

FireBaseJobdispatcher

如果你使用FirebaseJobDispatcherlib,你可以使用

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]
Run Code Online (Sandbox Code Playgroud)

检查您的服务是否已安排或运行.

强制您的任务运行

创建时,Job您将获得JOB_ID返回.
使用此选项JOB_ID强制作业运行.
您可以使用adb shell cmd jobscheduler run命令执行此操作(需要Android 7.1或更高版本).

例如,您的包名是com.foo.bar.application,而且JOB_ID是1.您现在可以通过运行您的任务adb

adb shell cmd jobscheduler run -f com.foo.bar.application 1
Run Code Online (Sandbox Code Playgroud)

不要忘记该-f选项,因为即使未满足设置的限制,这也会强制作业运行.

Evernote Android Job Lib

最后但并非最不重要.
使用Evernote的精彩图书馆.
它允许容易向后移植JobScheduler无论是在低级别的API使用JobScheduler,GcmNetworkManager或者AlarmManager根据您的API级别.

编辑24/08

甚至更好地使用firebase作业调度程序库.

火力地堡JobDispatcher是在Android应用调度后台作业的库.它提供了与JobScheduler兼容的API,适用于安装了Google Play服务的所有最新版本的Android(API级别9+).

我希望这有帮助.

谢谢

  • 好总结!我只是想补充一点,你写的所有内容都适用于Android 7及更高版本.自Android 5以来,JobScheduler已经登陆,输出不同.如果有人想知道的话. (3认同)
  • 输出确实显示"正在运行作业[FORCED]",但作业没有运行.使用Android O在模拟器上测试. (3认同)
  • 在“JOB #u0a93/17”中,JOB_ID 是 17 吗? (2认同)

Hen*_*ing 17

使用该命令adb shell dumpsys jobscheduler可以获得有关当前计划和活动作业的信息.

我注意到Android 6和7之间命令的输出差别很大.使用Android 5设备时输出很短,有时候很神秘.注册作业的有趣部分是在这里构建并在下面重复以方便,这应该有助于解密:

@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)" : "")
            + "]";
}
Run Code Online (Sandbox Code Playgroud)

另一方面,Android 7设备具有非常长的输出,具有更详细和更好的可读信息.还有更多的功能,如历史.缺点是你必须先找到有趣的部分.

我还没有找到一种强制作业运行的方法,但是有一个功能请求.请参阅p4u144的答案.


p4u*_*144 14

从Android 7.0开始,有一个新cmd的adb shell.在7.1中(仅在预览中),adb shell cmd jobscheduler已经添加了,因为您可以在此处看到强制运行JobScheduler.帮助说:

作业调度程序(jobscheduler)命令:help打印此帮助文本.

运行[-f | --force] [-u | --user USER_ID] PACKAGE JOB_ID触发特定预定作业的立即执行.选项:-f或--force:即使当前未满足连接等技术限制-u或--user:指定要运行哪个用户的作业,也要运行作业; 默认为主用户或系统用户