在Android中使用JobScheduler调度作业
我对新安卓API 21中的JobScheduler的作业调度有问题。 这是我以60秒的间隔安排作业的代码,如下所示:在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)
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;
}
}