我需要在Android应用的背景上定期运行网络任务。
我最初会使用AlarmManager
(不能使用JobScheduler
因为它必须在棒棒糖前设备上工作),但后来我遇到了{{1}这似乎更容易使用,并提供了一个更简单的API,如果设备连接到互联网,它负责运行任务(也不需要使用广播接收器,因此维护的类更少)。
我遇到的问题是我需要运行的任务由3个异步步骤组成,而GcmNetworkManager
似乎是为了运行同步任务而创建的。
我已对此进行了测试,发现我的异步任务运行得很好,直到GcmTaskService
内部结束(我的服务随后停止),但是我担心这可能更巧合,因为我的异步任务非常快,而不是服务没有在GcmTaskService
代码中停止的事实(我试图查看代码,但是它被混淆了所以它很难理解它是什么一样)。
有人知道GcmTaskService
实际上是否会在扩展类停止它之前运行,或者在同步任务结束时它是否会被停止?
答案 0 :(得分:3)
经过一番调查和调试后,我找到了答案。我会在这里描述一下,也许它可以在将来帮助其他人。
正如我所怀疑的那样,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);
}
}
}
此方法在完成任务后从运行任务的线程调用(在onRunTask()
返回后的a.k.a.)。
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 Play服务版本上发生根本变化,在这种情况下,它可能会破坏此功能(不太可能,但可能) 。所以我想我会选择AlarmManager
而不是为了安全。
答案 1 :(得分:1)
GcmTaskService
仅运行您的任务3分钟,之后计为超时。因此,如果您有大尺寸任务,我建议您创建自己的服务
有关GcmTaskService
:read this
答案 2 :(得分:0)
从TaskService的onRunTask开始自己的服务怎么样? 瘸子,但可能最安全......或者?