我需要在Android应用程序的背景下定期运行一个网络任务。
我最初打算使用AlarmManager (不能使用JobScheduler,因为它必须在以前的棒棒糖设备上工作),但后来我遇到了似乎更容易使用的GcmNetworkManager,它提供了一个更容易使用的API,如果设备连接到互联网上,它会负责运行任务(也不需要使用广播接收器,所以维护的类更少)。
我遇到的问题是,我需要运行的任务由3个异步步骤组成,而创建GcmTaskService似乎是为了运行同步任务。
我对此进行了测试,并发现我的异步任务一直运行到GcmTaskService内部(我的服务随后停止)才结束,但是我担心这可能更像是巧合,因为我的异步任务非常快,而不是服务在GcmTaskService代码中没有停止(我试图查看代码,但它是模糊的,所以很难理解它做了什么)。
是否有人知道GcmTaskService实际上是在扩展类停止之前运行,还是在同步任务结束时被停止?
发布于 2016-01-27 22:41:56
经过一番调查和调试,我找到了答案。我会在这里描述,这样也许它能在将来帮助到其他人。
正如我所怀疑的,当所有需要运行的任务都完成(这很有意义)时,GcmTaskService就会停止运行。这个方法(在GcmTaskService类中)证明了这一点:
private void zzdJ(String var1) {
Set var2 = this.zzaIU;
synchronized(this.zzaIU) {
this.zzaIU.remove(var1);
if(this.zzaIU.size() == 0) {
this.stopSelf(this.zzaIV);
}
}
}在任务完成(a.k.a )之后,将从运行该任务的线程调用此方法。在onRunTask()返回之后)。
var1是开发人员在创建任务时分配给它的标记,而zzaIU是该服务需要运行的任务列表。因此,正如我们所看到的,已经完成的任务将从列表中删除,如果没有剩下的要运行的任务,则服务将停止。
可能的解决方案:
但是,有一种可能的解决方案可以在GcmTaskService中运行异步任务。为此,我们需要重写onStartCommand()方法,以防止GcmTaskService在另一个线程中启动任务。
代码将如下所示:
private boolean taskRunning = false;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String intentAction = intent.getAction();
if (SERVICE_ACTION_EXECUTE_TASK.equals(intentAction)) {
taskRunning = true;
// Run your async tasks. Make sure to stop the service when they end.
} else if (SERVICE_ACTION_INITIALIZE.equals(intentAction)) {
// Initialize tasks if needed (most likely not needed if they are running asynchronously)
// If this step is not needed, make sure to stop the service if the tasks already run (this could be called after
// the service run all the tasks, and if we don't stop the service it'll stay running on the background without doing
// anything)
if (!taskRunning) {
stopSelf();
}
}
return START_NOT_STICKY;
}
@Override
public int onRunTask(TaskParams taskParams) {
// IMPORTANT: This method will not be run, since we have overridden the onStartCommand() to handle the tasks run ourselves,
// which was needed because our tasks are asynchronous
return GcmNetworkManager.RESULT_SUCCESS;
}只有当该服务被开发为运行1个任务时,如果需要运行多个任务,则需要使用一个列表而不是taskRunning布尔值,并检查其大小以查看是否需要在停止服务之前运行更多的任务(就像原始的GcmTaskService代码那样),这才能起作用。
尽管这是一个解决方案,但这并不是未来的证据,因为GcmTaskService上的代码可能会在未来的Google服务版本中发生根本性的变化,在这种情况下,它可能会破坏这一功能(不太可能,但可能)。所以,为了安全起见,我想我还是选择AlarmManager吧。
发布于 2016-01-27 04:26:20
GcmTaskService只运行你的任务3分钟,之后它就被计算为超时。因此,如果您有较大的任务,我建议您创建您自己的服务。
更多关于GcmTaskService:阅读这篇文章的信息
发布于 2016-08-14 21:47:03
从TaskService的onRunTask开始自己的服务怎么样?站不住脚,但可能是最安全的...or?
https://stackoverflow.com/questions/35028601
复制相似问题