使用 firebase 作业调度程序安排重复作业

Posted

技术标签:

【中文标题】使用 firebase 作业调度程序安排重复作业【英文标题】:Schedule recurring job using firebase job dispatcher 【发布时间】:2017-03-14 10:29:37 【问题描述】:

我正在尝试每 10 分钟将 android 设备的位置发布到服务器。我正在使用 Firebase 作业调度程序来执行此操作

FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));
Job myJob = dispatcher.newJobBuilder()
    .setService(UpdateLocationService.class)
    .setRecurring(true)
    .setTrigger(Trigger.executionWindow(10, 20))
    .setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
    .setTag("location-update-job")
    .setLifetime(Lifetime.FOREVER)
    .build();
dispatcher.mustSchedule(myJob);

UpdateLocationService 获取位置并发送到服务器。

我的问题:大部分工作正常。唯一的问题是,作业安排的时间差为 4m、6m、7m、8m、10m、16m、23m...

谁能帮我理解一下。

更新:我希望在 10-20 分钟内获得一次该位置。在上面的代码中,值太低只是为了测试目的

【问题讨论】:

如果作业失败,那么我想会有退避。我也相信不能保证在那个确切的时刻运行。将您的退避与可变的开始时间结合起来可以解释时间安排。您是否在 onStopJob() 中返回了正确的布尔值? @kranthi117 你找到答案了吗? @SharpEdge 还没有:( 2019年解决了吗?有什么解决办法吗? 【参考方案1】:

还有:

Trigger.executionWindow(windowStart, windowEnd)

预计 windowStartwindowEnd 以秒为单位。根据您的要求,您希望窗口为 10 分钟。所以你应该使用类似的东西:

Trigger.executionWindow(10*60, 20*60)

【讨论】:

【参考方案2】:

发生这种情况的原因有几个。首先,您的工作是在onStopJob() 中返回false 吗?来自文档

@Override
public boolean onStopJob(JobParameters job) 
    return false; // Answers the question: "Should this job be retried?"

如果需要重试作业,则将应用退避。将此与您希望它每 10-20 秒再次运行的事实相结合,您可能会得到您所遇到的结果。

您没有为作业设置任何约束,这也会影响它的运行时间。例如

.setConstraints( // only run on an unmetered network Constraint.ON_UNMETERED_NETWORK, // only run when the device is charging Constraint.DEVICE_CHARGING )

此外,我会为您正在做的事情使用预定的工作。查看 Google API 客户端,它提供来自 fused location provider 的定期更新。

您可以像这样在您的服务或活动上实现回调

public class MainActivity extends ActionBarActivity implements
        ConnectionCallbacks, OnConnectionFailedListener, LocationListener 
    ...
    @Override
    public void onLocationChanged(Location location) 
        mCurrentLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
        updateUI();
    

    private void updateUI() 
        mLatitudeTextView.setText(String.valueOf(mCurrentLocation.getLatitude()));
        mLongitudeTextView.setText(String.valueOf(mCurrentLocation.getLongitude()));
        mLastUpdateTimeTextView.setText(mLastUpdateTime);
    

在此处查看完整文档,但我相信您将获得更一致的服务体验,这些服务致力于您想要实现的目标。

https://developer.android.com/training/location/receive-location-updates.html

【讨论】:

关于onStopJob,我尝试了truefalse。没有运气。关于融合位置提供者,是的,我正在使用它来确定当前位置。 但是您也可以使用 LocationChanged 回调来替换计划的作业。 我尝试了您链接到的文档。但这需要一个活跃的 Activity 或 Service,带有 Doze 模式和 AppStandby,这太让人头疼了 我不知道你的情况,但我可以说我肯定会卸载一个不断需要位置更新并且每 10-20 秒耗尽我的电池的应用程序,即使该应用程序没有运行。它的性能不高,实际上我怀疑您是否需要在后台每 10-20 秒运行一次作业。 Android 正在尝试使用您提到的功能来节省电池电量,所以我想有一种更好的方式来做您想做的事情,但使用不同的方法。 @GrahamSmith OP 在他的问题中明确表示,他希望设备位置每 10 分钟一次。“我正在尝试每 10 分钟将 android 设备的位置发布到服务器”所以它相当实际使用它,实际上我的公司还给了我每 15 分钟获取一次设备位置的任务,因为我们需要用户的位置,以便服务器根据他当前的位置来决定工作机会。【参考方案3】:

ExecutionWindow 指定大致时间。不能保证作业将在给定窗口运行。如果它错过了窗口,则作业将在理想情况下最早运行。对于重复作业,一旦作业完成,下一个作业将根据作业上次运行的时间计算执行窗口时间。

LINK

ExecutionWindow 表示一次成为合格的 Job 触发器 当前经过的时间超过了预定时间 + @code windowStart 价值。鼓励调度程序后端使用 windowEnd 值作为 发出作业应该运行的信号,但这不是强制行为。

【讨论】:

以上是关于使用 firebase 作业调度程序安排重复作业的主要内容,如果未能解决你的问题,请参考以下文章

如何取消firebase作业调度程序中的重复作业

Firebase 作业调度员是不是需要互联网访问来安排作业?

如何使用调度包安排python作业每小时准确运行[重复]

使用作业调度程序管理定期任务?

firebase 作业调度程序在 android 中以打瞌睡模式工作。?

Firebase Jobdispatcher:由于错误而无休止运行的作业永远不会再次安排