到目前为止,我已经使用AlarmManager每30分钟发送一次HTTP请求。但最近,我在Google Play控制台中遇到了警告:过度唤醒。当我阅读警告详细信息时,它说AlarmManager过度唤醒设备。
然后我研究了我还能用什么来每 30 分钟发送一次请求。结果,我找到了这个文档。它建议使用 JobScheduler 或 JobDispatcher。首先,我尝试使用JobScheduler - 但它需要API 21,这对我来说并不重要。我需要在当前项目中支持 API 16 中的设备。然后我决定使用JobDispatcher。
这是我的工作服务:
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 分钟准确运行一次服务?如果不可能,在声明功能之前我还可以使用什么来实现?
您可以缩短可以触发作业的时间窗口。它可以帮助您稍微控制作业必须触发的时间余量。
// 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 +前台服务。请注意,适用于Android 6或更高版本的AlarmManager会有一点延迟(换句话说,警报不会在30分钟内触发)。