到目前为止,我已经使用AlarmManager每30分钟发送一次HTTP请求。但最近,我在Google Play控制台中遇到了警告:过度唤醒。当我读到警告细节时,它说AlarmManager过度唤醒设备。
然后我研究了我每30分钟可以用来发送请求的其他内容。结果,我找到了documentation。它建议使用JobScheduler或JobDispatcher。首先,我尝试使用JobScheduler - 但它需要API 21,这对我来说并不好。我需要在当前项目中支持API 16中的设备。然后我决定使用JobDispatcher。
这是我的JobService:
public class MyJobService extends JobService {
@Override
public boolean onStartJob(final JobParameters params) {
Log.d("JobDispatcherLog", params.getTag()+ " STARTED");
jobFinished(params, true);
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.d("JobDispatcherLog", params.getTag()+ " STOPPED");
return false;
}
}
这是我创建应该每30分钟运行一次服务的工作。
FirebaseJobDispatcher dispatcher =
new FirebaseJobDispatcher(new GooglePlayDriver(this));
RetryStrategy retryStrategy =
dispatcher.newRetryStrategy(
RetryStrategy.RETRY_POLICY_LINEAR, 1800, 86400);
Job job = dispatcher.newJobBuilder()
.setService(MyJobService.class)
.setTag("very-important-job")
.setLifetime(Lifetime.FOREVER)
.setReplaceCurrent(true)
.setRetryStrategy(retryStrategy)
.setConstraints(Constraint.ON_ANY_NETWORK)
.build();
dispatcher.mustSchedule(job);
我测试了这段代码并在LogCat中获得了以下结果:
03-16 18:01:08.540 D/JobDispatcherLog: very-important-job STARTED
03-16 18:43:41.747 D/JobDispatcherLog: very-important-job STARTED
03-16 20:12:01.361 D/JobDispatcherLog: very-important-job STARTED
正如您所看到的,它并非每30分钟运行一次。
我的问题:这是JobDispatcher的正常行为吗?如何每隔30分钟运行一次服务?如果不可能,在陈述功能之前还可以用什么来实现?
答案 0 :(得分:1)
您可以缩短触发作业的时间窗口。它可以帮助您控制作业必须触发的时间范围。
// Create a new FirebaseJobDispatcher with the driver
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(driver);
// Building the Job.
Job yourJob = dispatcher.newJobBuilder()
.setService(YourJobService.class) // The Job service that will execute.
.setTag(YOUR_JOB_TAG) // Unique Tag.
.setLifetime(Lifetime.FOREVER) // To make it last "forever".
.setRecurring(true) // To make it repetitive
/* setTrigger is your time window. You can adjust the SYNC_FLEXTIME_SECONDS to reduce the window a little. But it is not guaranteed to be .*/
.setTrigger(Trigger.executionWindow(ALARM_INTERVAL_SECONDS, ALARM_INTERVAL_SECONDS + SYNC_FLEXTIME_SECONDS))
.setReplaceCurrent(true) // To make it to overwrite a previous job created with the same tag.
.build();
注意:请注意,如果您要使用FirejobDispatcher(或JobScheduler),则无法保证您的服务每30分钟就会触发一次。
如果您想要更精确的警报"那么你必须倾向于使用AlarmManager + Foreground Service。请注意,适用于Android 6或更高版本的AlarmManager会有一点延迟(换句话说,警报不会在30分钟内触发)。