JobScheduler:控制从满足约束到运行作业的延迟 [英] JobScheduler: controlling delay from constraints being met to job being run

查看:123
本文介绍了JobScheduler:控制从满足约束到运行作业的延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JobScheduler安排工作。主要是我将其用于 .setRequiredNetworkType()方法,该方法可让您指定仅希望在网络连接时安排作业(或更具体地说,

I'm using JobScheduler to schedule jobs. Mainly I'm using it for the .setRequiredNetworkType() method, which allows you to specify that you only want the job to be scheduled when a network connection (or more specifically an unmetered connection) is established.

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

I'm using the following pretty straightforward code to schedule my jobs:

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);

因此,在调度上只有一个约束:网络连接(可能是任何或未计量)。

So there is just one constraint placed on the scheduling: a network connection (which may be 'any' or 'unmetered').

如何指定所有对象的最大延迟满足约束条件并实际运行工作,例如在有网络连接的2秒钟内运行作业?

How do I specify a maximum delay from all constraints being met, and actually running the job, e.g. "run the job within 2 seconds of there being a network connection"?

问题

我发现的是,在某些设备上,如果计划在网络限制为已经很满意,该作业将立即运行(或足够快地被用户感知)。

What I'm finding is that on some devices, if a job is scheduled during a period in which the network constraint is already satisfied, the job will run immediately (or quickly enough to be perceived as so by the user).

但是在其他设备上,甚至如果已经有合适的网络连接(以便该作业可以立即运行),则在实际运行之前会有很大的延迟。因此,如果这是对用户操作的响应,则印象是什么都没有发生,并且应用程序已损坏。

But on other devices, even if a suitable network connection is already available (so that the job could run immediately), there is a significant delay before it actually runs. So if this is in response to a user action, the impression is that nothing has happened and that the app is broken.

现在,我知道这是 JobScheduler 的意图可能是...由系统来安排作业以使其最适合其他需求,并且不能保证该作业可以运行

Now, I'm well aware that this is probably the intention with JobScheduler... that it's up to the system to schedule the job to best fit in with other demands, and that there is no guarantee that the job will run immediately when all constraints are satisfied.

但是能够在需要时对 some 进行控制将是一件很不错的事情。因此,对于按计划进行的工作而无需用户参与,对系统进行精确定时的完全控制是很好的。

But it would be nice to be able to have some control over it, where required. So for jobs that happen on a schedule, without user involvement, giving the system complete control over precise timing is fine and good.

但是该作业是响应用户操作的,我希望该作业能够无延迟运行...假设存在网络连接。 (如果没有连接,则会显示一条消息,指示恢复网络连接时将执行该操作,然后 JobScheduler 会确保在网络已恢复。)

But where the job is in response to a user action, I want the job to run without delay... assuming the network connection is there. (If there is no connection, a message can be displayed that the action will happen when a network connection is restored, and the JobScheduler then takes care of ensuring the job runs when the network is restored.)

setOverrideDeadline()不是解决方案吗?

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

I can see that JobInfo.Builder does have a setOverrideDeadline() method, which is almost what I want. But that specifies the maximum delay from when the job is scheduled (i.e. run the job in 10 seconds' time even if all constraints are not met), and not from when all constraints have been satisfied (i.e. run the job within 10 seconds of all constraints being satisfied).

编辑:并且似乎存在一个令人讨厌的错误,它可能导致作业使用 setOverrideDeadline()运行两次:请参见

and there seems to be an annoying bug which can result in the job being run twice when using setOverrideDeadline(): see here and here.

Firebase JobDispatcher怎么样?

我看到 Firebase JobDispatcher 具有 Trigger.NOW 触发器(意味着作业应在其运行时约束得到满足后立即运行)。如果 JobScheduler 不本地支持,那也许就是这样的方法?我被Firebase JobDispatcher推迟了,因为它似乎正在使用大锤破解螺母……而且看来Firebase完全是关于云消息传递等的,与本地任务调度相去甚远(应该是完全是本地关注的问题)。它似乎需要Google Play服务,这对于本地任务调度来说似乎完全没有必要。此外,如果使用Firebase立即触发触发,并且Firebase仅将 JobScheduler 用于Android L +,那么肯定可以直接使用 JobScheduler执行此操作不用依靠Firebase吗?

I see that Firebase JobDispatcher has a Trigger.NOW trigger ("means that the Job should be run as soon as its runtime constraints are satisfied"). Perhaps that's the way to go if JobSchedulerdoesn't support this natively? I've been put off by Firebase JobDispatcher because it seems like it's using a sledgehammer to crack a nut... and it appears that Firebase is all about cloud messaging etc, which is very far removed from local task scheduling (which should be an entirely local concern). And it seems to require Google Play services, which again seems completely unnecessary for local task scheduling. Furthermore, if immediate triggering it possible with Firebase, and Firebase just uses JobScheduler for Android L+, then it must surely be possible to do this directly with JobScheduler without relying on Firebase?

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

I've now tried this, and even Trigger.NOW doesn't guarantee an immediate response... in fact I am finding that there is a delay of almost exactly 30 seconds on my device, which is odd.

失败...

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

At present, the only way I can see to ensure immediate execution (if constraints are met) is to not use JobScheduler.

或者手动执行初始约束检查并运行如果满足所有约束,则 setOverrideDeadline()为0的作业,否则运行时不<< c $ c> setOverrideDeadline()。

Or maybe do the initial constraints check manually, and run the job with a setOverrideDeadline() of 0 if all constraints are met, otherwise run it without setOverrideDeadline().

仅仅具有控制 Job的时间的能力似乎是可取的。 Scheduler 本身,有点像您可以使用 AlarmManager setWindow() 方法c>。

It would seem far preferable just to have the ability to control the timing of JobScheduler itself, a bit like you can with the setWindow() method of AlarmManager.

推荐答案

作业调度程序用于调度作业:定期触发,有延迟或对其他作业有限制。
如果您想立即解雇工作,则无需安排时间,只需启动它即可。

A job scheduler is to schedule jobs: triggering periodically, with delay or with constraints to other jobs. If you want to fire a job instantly, it doesn't need to bee scheduled, just launch it.

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);
    }

这篇关于JobScheduler:控制从满足约束到运行作业的延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆