android - 作业调度程序 : controlling delay from constraints being met to job being run

标签 android alarmmanager android-jobscheduler

我正在使用 JobScheduler 来安排作业。主要是我将它用于 .setRequiredNetworkType()方法,它允许您指定只希望在建立网络连接(或更具体地说是非计量连接)时安排作业。

我正在使用以下非常简单的代码来安排我的工作:

PersistableBundle extras = new PersistableBundle();
extras.putInt("anExtraInt", someInt);
int networkConstraint = useUnmetered ? JobInfo.NETWORK_TYPE_UNMETERED : JobInfo.NETWORK_TYPE_ANY;

ComponentName componentName = new ComponentName(context, MyJobService.class);
JobInfo jobInfo = new JobInfo.Builder(jobId, componentName)
        .setRequiredNetworkType(networkConstraint)
        .setExtras(extras)
        .build();

JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(jobInfo);

所以对调度只有一个限制:网络连接(可能是“任意”或“不限流量”)。

问题的简短版本

我如何指定满足所有约束并实际运行作业的最大延迟,例如“在有网络连接的 2 秒内运行作业”?

更长的版本(有杂文)

问题

我发现在某些设备上,如果在已经满足网络约束的时期安排了作业,则作业将立即运行(或足够快以被用户感知)。

但是在其他设备上,即使合适的网络连接已经可用(以便作业可以立即运行),在它实际运行之前也存在明显的延迟。因此,如果这是为了响应用户操作,给人的印象是什么都没有发生并且应用程序已损坏。

现在,我很清楚这可能是 JobScheduler 的 Intent 。 ...由系统来安排作业以最好地满足其他需求,并且不能保证在满足所有约束时作业会立即运行。

但是,如果需要,能够对其进行一些控制会很好。因此,对于按计划发生的工作,没有用户参与,让系统完全控制精确的时间是很好的。

但是,在该作业响应用户操作的情况下,我希望该作业能够毫不延迟地运行......假设网络连接在那里。 (如果没有连接,可以显示一条消息,当网络连接恢复时将发生该操作,然后 JobScheduler 负责确保在网络恢复时作业运行。)

setOverrideDeadline() 不是解决方案吗?

我可以看到 JobInfo.Builder 确实有 setOverrideDeadline() 方法,这几乎是我想要的。但这指定了最大延迟 从作业计划时间开始 (即,即使不满足所有约束,也要在 10 秒内运行作业),而不是 从满足所有约束条件开始 (即在满足所有约束的 10 秒内运行作业)。

编辑:似乎有一个令人讨厌的错误,它会导致作业在使用 setOverrideDeadline() 时运行两次: 见 herehere .

Firebase JobDispatcher 怎么样?

我看到了 Firebase JobDispatcher有一个 Trigger.NOW trigger (“意味着只要满足运行时约束,就应该运行作业”)。如果JobScheduler,也许这就是要走的路不支持这个本地?我已经被 Firebase JobDispatcher 推迟了,因为它似乎在使用大锤来破解坚果......而且 Firebase 似乎完全是关于云消息传递等,这与本地任务调度相去甚远(这应该是一个完全本地关注)。而且它似乎需要 Google Play 服务,这对于本地任务调度来说似乎完全没有必要。此外,如果使用 Firebase 立即触发它是可能的,而 Firebase 只使用 JobScheduler对于 Android L+,那么肯定可以直接使用 JobScheduler 执行此操作不依赖 Firebase?

编辑:我现在已经尝试过这个,甚至 Trigger.NOW不保证立即响应......事实上,我发现我的设备上几乎有 30 秒的延迟,这很奇怪。

如果失败...

目前,我可以看到确保立即执行(如果满足约束)的唯一方法是不使用 JobScheduler .

或者手动进行初始约束检查,然后使用 setOverrideDeadline() 运行作业。如果满足所有约束,则为 0,否则在没有 setOverrideDeadline() 的情况下运行它.

能够控制 JobScheduler 的时间似乎更可取。本身,有点像您可以使用 setWindow() AlarmManager的方法.

最佳答案

作业调度程序用于调度作业:定期触发、延迟或限制其他作业。
如果你想立即解雇一个工作,它不需要蜜蜂调度,只需启动它。

ConnectivityManager cm =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = cm.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnectedOrConnecting()) {

        // If there is connectivity, Launch the job directly here

    } else {

        PersistableBundle extras = new PersistableBundle();
        extras.putInt("anExtraInt", someInt);
        int networkConstraint = useUnmetered ?       
        JobInfo.NETWORK_TYPE_UNMETERED : JobInfo.NETWORK_TYPE_ANY;

        ComponentName componentName = new ComponentName(context,MyJobService.class);
        JobInfo jobInfo = new JobInfo.Builder(jobId, componentName)
                .setRequiredNetworkType(networkConstraint)
                .setExtras(extras)
                .build();

        JobScheduler jobScheduler = (JobScheduler)      context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
        jobScheduler.schedule(jobInfo);
    }

关于android - 作业调度程序 : controlling delay from constraints being met to job being run,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39363839/

相关文章:

Android Job Scheduler 仅在应用程序在 Android M 上打开时运行作业 (6)

javascript - 将新数据推送到 firebase 数据库时设置自定义数字键

java - 如何将操作栏中带有微调器的按钮更改为加载?

上一页和下一页可见的Android ViewPager?

java - 无法取消 Android 闹钟管理器的闹钟

java - 每次互联网可用时运行工作人员

Android Studio Gradle 构建失败。错误 :Cause: peer not authenticated

android - AlarmManager 在不同时间触发

java - AlarmManager 不准确

android - 使用工作管理器获取远程异常