我创建了一个非常简单的服务,用于更新服务器上的用户位置:
public class LocationSchedulerService extends GcmTaskService {
@Override
public int onRunTask(TaskParams taskParams) {
// Update to server stuff
return GcmNetworkManager.RESULT_SUCCESS;
}
}我创建了一个简单的BootBroadcastReceiver,以便在设备启动时启动服务:
PeriodicTask task = new PeriodicTask.Builder()
.setTag("LocationSchedulerService")
.setService(LocationSchedulerService.class)
.setPeriod(LOCATION_UPDATE_PERIOD * 60)
.setFlex(LOCATION_UPDATE_FLEX * 60)
.setPersisted(false)
.setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)
.setRequiresCharging(false)
.setUpdateCurrent(true)
.build();
GcmNetworkManager.getInstance(context).schedule(task);现在我的问题是:
由于不可能知道用户何时安装了包,所以我也希望在用户启动应用程序时启动此任务。但是,如何防止任务运行两次呢?
我读过setUpdateCurrent的文档,但不确定它的功能。这是否意味着当前运行的服务将被取消,或者它正是我想要的?
发布于 2015-06-20 00:06:26
您所描述的就是为什么引入了setUpdateCurrent --应用程序想要一种“只在任务还不存在的情况下才安排任务”的方法。
但是,您所说的“如何防止任务运行两次”是什么意思呢?您正在调度一个PeriodicTask,这意味着任务将每(LOCATION_UPDATE_PERIOD * 60)秒执行一次。
听起来,默认的setUpdateCurrent=false是您想要的,您可以在BOOT_COMPLETED和您的onCreate()中为您的应用程序安排PeriodicTask。
如果您担心在第一次启动时希望立即更新位置,然后默认为每秒钟更新一次,则可以在onCreate中编写代码以:检查第一次启动(可能是写入shared_prefs文件,如果值不存在,则知道它是第一次启动)如果第一次启动,则安排一个特殊的OneoffTask在下一分钟执行。给这个OneoffTask一个像"LocationSchedulerService:first_boot“这样的特殊标签
然后在您的LocationSchedulerService中扩展GcmTaskService:
public int onRunTask{
if (tag.equals("LocationSchedulerService:first_boot")) {
performLocationUpdate();
// Now that you've done the one time update, fall back to
// your original schedule
PeriodicTask task = new PeriodicTask.Builder()
.setTag("LocationSchedulerService")
.setService(LocationSchedulerService.class)
.setPeriod(LOCATION_UPDATE_PERIOD * 60)
.setFlex(LOCATION_UPDATE_FLEX * 60)
.setPersisted(false)
.setRequiredNetwork(Task.NETWORK_STATE_CONNECTED) // not needed, default
.setRequiresCharging(false) // not needed, default
.setUpdateCurrent(true) // not needed, you know this is 1st time
.build();
GcmNetworkManager.getInstance(context).schedule(task);
} else if tag.equals("LocationSchedulerService") {
performLocationUpdate();
} else {
// error
}顺便说一句,您不需要BOOT_COMPLETED接收器。GcmNetworkManager的思想是允许您通过设置persisted=true来避免这种情况。这样,您就可以知道您的任务将在重新启动过程中持久化。通常只需在onCreate中安排一次就足够了。
发布于 2015-06-03 12:39:21
从文档中可以看出,调用setUpdateCurrent(true)将使用相同的标记更新PeriodicTask的调度约束。
可选的setter指定此任务是否应覆盖任何具有相同标记的预先存在的任务。这默认为false,这意味着新任务不会覆盖现有任务。
另外,您还可以在使用Task计划新的GcmNetworkManager.cancelTask()之前取消您的GcmNetworkManager.cancelTask()。
发布于 2015-07-11 16:44:35
因为您的目标是让GcmTaskService始终运行,包括通过重新启动,所以您所需要做的就是setPersisted(true),而不是问题中的示例代码中的错误。
来自文档
公共PeriodicTask.Builder setPersisted (布尔isPersisted) 可选的setter指定此任务是否应在重新启动时持久化。对于周期性任务,这默认为true,调用方必须持有权限android.Manifest.permission.RECEIVE_BOOT_COMPLETED,,否则此设置程序将被忽略。
所以,不要担心自己的BootBroadcastReceiver,只需添加引导权限即可。
因为主要的问题是防止GcmTaskService同时多次运行。这可以通过对任务使用相同的标记来完成。默认情况下,如果任务(同名)已经在运行,那么就会发生。通过执行setUpdateCurrent(true),任务的参数将在调用schedule()时被更新/替换。
https://stackoverflow.com/questions/30619582
复制相似问题