0

到目前为止,我已经使用 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 分钟运行一次服务?如果不可能,我还能用什么来实现之前声明的功能?

4

1 回答 1

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 分钟内触发)。

于 2018-03-16T16:19:36.657 回答