在Android中使用JobScheduler调度作业

在Android中使用JobScheduler调度作业,android,task,scheduling,jobs,android-jobscheduler,Android,Task,Scheduling,Jobs,Android Jobscheduler,我对新安卓API 21中的JobScheduler的作业调度有问题。 这是我以60秒的间隔安排作业的代码,如下所示: ComponentName serviceName = new ComponentName(this, MyJobService.class); JobInfo jobInfo = new JobInfo.Builder(0, serviceName) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)

我对新安卓API 21中的JobScheduler的作业调度有问题。 这是我以60秒的间隔安排作业的代码,如下所示:

ComponentName serviceName = new ComponentName(this, MyJobService.class);
JobInfo jobInfo = new JobInfo.Builder(0, serviceName)
        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
        .setPeriodic(60000)
        .build();
我的JobService仅在Logcat中打印运行时间,但日志显示服务在此时刻运行:

03-18 08:37:26.334: I/JOB(32662): Wed Mar 18 08:37:26 BRT 2015
03-18 08:37:56.364: I/JOB(32662): Wed Mar 18 08:37:56 BRT 2015
03-18 08:39:21.418: I/JOB(32662): Wed Mar 18 08:39:21 BRT 2015
03-18 08:41:51.670: I/JOB(32662): Wed Mar 18 08:41:51 BRT 2015
03-18 08:45:52.192: I/JOB(32662): Wed Mar 18 08:45:52 BRT 2015
03-18 08:54:20.678: I/JOB(32662): Wed Mar 18 08:54:20 BRT 2015
这很奇怪,因为我用setPeriodic(60000)方法设置的作业应该在1分钟内至少执行1次。 这也是奇怪的间隔如何增加之间的运行。此时,时间是2015年3月18日星期三09:09:00 BRT,不再执行该工作


这是JobScheduler API的问题吗?(我运行的是Nexus5和Android 5.0.1)

时间的变化与重试作业的退避标准有关。默认情况下,它设置为指数。我猜当您通过调用
jobFinished(JobParameters params,boolean needsReschedule)
完成作业时,您也没有正确完成作业


我写了一篇文章,把重点放在JobScheduler的所有小事情上。我强烈建议您阅读。

我也有同样的问题,我认为这可能与JobInfo类的内部要求有关:


看起来JobInfo不允许您将间隔设置为小于此值。

//下面是我在其中一个项目中使用的代码,它对我来说运行良好

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void scheduleJob(Context context) {
        //https://kb.sos-berlin.com/pages/viewpage.action?pageId=3638048
        //Scheduler uses UTC times for all its internal operations. This ensures a continual flow of operation without breaks or repetitions regardless of any changes in local time.
        JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(context, MyService.class));//JobSchedulerService.class.getName()));
        builder.setPersisted(true); //persist across device reboots

        builder.setPeriodic((120 * 60 * 1000)); //run once after 2 hours seconds

        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); // only if wifi avaiblable so they are not using bandwith
        builder.setRequiresDeviceIdle(false); // run not only if the device is idle
        builder.setRequiresCharging(false); // run not only if the device is charging

       // android.os.PersistableBundle bundle = new android.os.PersistableBundle();
        // bundle.putString(WEB_SERVICE_URL, "http://example.com?upload.php");
        //   builder.setExtras(bundle);

        //builder.setBackoffCriteria(1600, JobInfo.BACKOFF_POLICY_LINEAR);
        //BACKOFF_POLICY_LINEAR After one failure retry at 1 * your value, then at 2 * (your value), then 3 * (your value) and so on
        //BACKOFF_POLICY_EXPONENTIAL After one failure retry at your value, then at (your value)^2, (your value)^3 and so on
        //builder.setMinimumLatency(5 * 1000); //latency
        //builder.setOverrideDeadline(50 * 1000); //wait for criteria to be met, in 50 seconds if they have not then run anyways


        int test = jobScheduler.schedule(builder.build());
        if (test <= 0) {
            Utility.showDialog(context, "Service Error", "Service is not responding");
            //If something goes wrong
        }
    }

作业调度器工作得很好,但是如果我锁定屏幕,时间间隔会持续变化。任何解决方案对我来说都有效。作业调度器做得不好的一件事是确保作业运行的准确时间。我认为这将是一个按预期工作的情况。不过,通过与你的情妇玩游戏,你或许可以修复它。从技术上讲,现在应该改用WorkManager。几周前有一次谷歌IO的讨论。我已经试过了,问题是工作经理允许每15分钟做一次作业,我必须每60秒运行一次作业,任何其他方法我都可以在精确的时间范围内达到结果,我已经发布了一个问题,你能告诉我如何在没有时间延迟的情况下完成吗
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void scheduleJob(Context context) {
        //https://kb.sos-berlin.com/pages/viewpage.action?pageId=3638048
        //Scheduler uses UTC times for all its internal operations. This ensures a continual flow of operation without breaks or repetitions regardless of any changes in local time.
        JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(context, MyService.class));//JobSchedulerService.class.getName()));
        builder.setPersisted(true); //persist across device reboots

        builder.setPeriodic((120 * 60 * 1000)); //run once after 2 hours seconds

        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); // only if wifi avaiblable so they are not using bandwith
        builder.setRequiresDeviceIdle(false); // run not only if the device is idle
        builder.setRequiresCharging(false); // run not only if the device is charging

       // android.os.PersistableBundle bundle = new android.os.PersistableBundle();
        // bundle.putString(WEB_SERVICE_URL, "http://example.com?upload.php");
        //   builder.setExtras(bundle);

        //builder.setBackoffCriteria(1600, JobInfo.BACKOFF_POLICY_LINEAR);
        //BACKOFF_POLICY_LINEAR After one failure retry at 1 * your value, then at 2 * (your value), then 3 * (your value) and so on
        //BACKOFF_POLICY_EXPONENTIAL After one failure retry at your value, then at (your value)^2, (your value)^3 and so on
        //builder.setMinimumLatency(5 * 1000); //latency
        //builder.setOverrideDeadline(50 * 1000); //wait for criteria to be met, in 50 seconds if they have not then run anyways


        int test = jobScheduler.schedule(builder.build());
        if (test <= 0) {
            Utility.showDialog(context, "Service Error", "Service is not responding");
            //If something goes wrong
        }
    }
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class MyService extends JobService {

    @Override
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public boolean onStartJob(final JobParameters params) {

        Log.e(TAG, "onStartJob");

        String month = "3";
        String year = "2018";           
MyAsync myAsync = new MyAsync(MyService.this, arraydata, month, year, new SyncAsyncListener() {
                    @Override
                    public void onDataSuccess() {
                        try {
                            jobFinished(params, result);
                        } catch (Exception e) {

                        }
                    }
                });

                myAsync.execute();
            }
    return result;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
    return false;
}
}