Android GcmTaskService能否运行异步任务?
我需要在Android应用程序的后台定期运行网络任务 我最初打算使用Android GcmTaskService能否运行异步任务?,android,google-play-services,Android,Google Play Services,我需要在Android应用程序的后台定期运行网络任务 我最初打算使用AlarmManager(不能使用JobScheduler,因为它必须在棒棒糖前的设备上工作),但后来我遇到了GcmNetworkManager,它似乎更易于使用,并提供了更简单的API,如果设备连接到internet,它负责运行任务(也不需要使用广播接收器,因此需要维护的类更少) 我遇到的问题是,我需要运行的任务由3个异步步骤组成,gcmtasksservice似乎是为了运行同步任务而创建的 我已经对此进行了测试,发现我的异步
AlarmManager
(不能使用JobScheduler
,因为它必须在棒棒糖前的设备上工作),但后来我遇到了GcmNetworkManager
,它似乎更易于使用,并提供了更简单的API,如果设备连接到internet,它负责运行任务(也不需要使用广播接收器,因此需要维护的类更少)
我遇到的问题是,我需要运行的任务由3个异步步骤组成,gcmtasksservice
似乎是为了运行同步任务而创建的
我已经对此进行了测试,发现我的异步任务在gcmtasksservice
中一直运行良好(然后我的服务会自动停止),但是我担心这可能是巧合,因为我的异步任务非常快,而不是服务在gcmtasksservice
代码中没有停止(我试图查看代码,但代码很模糊,所以很难理解它的功能)
有人知道在扩展类停止之前,
gcmtasksservice
实际上是否会运行,或者在同步任务结束时它是否会停止吗?gcmtasksservice
只运行任务3分钟,之后它将计为超时。因此,如果您有大型任务,我建议您创建自己的服务。更多关于
gcmtasksservice
:经过一些调查和调试,我找到了一个答案。我将在这里描述它,以便将来它可能会帮助其他人
正如我所怀疑的,gcmtasksservice
在它需要运行的所有任务都完成时会自动停止(这很有意义)。这一点的证明就在这个方法上(在gcmtasksservice
类中):
此方法是在任务完成后从运行该任务的线程调用的(也称为onRunTask()
返回后)
var1
是开发人员在创建任务时分配给任务的标记,zzaIU
是需要此服务运行的任务列表。因此,正如我们所看到的,已完成的任务将从列表中删除,如果没有更多的任务可以运行,则停止服务
可能的解决方案:
但是,有一种可能的解决方案可以在gcmtasksservice
中运行异步任务。为此,我们需要重写onStartCommand()
方法,以防止gcmtasksservice
在另一个线程中启动任务
代码如下所示:
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
布尔值,并在停止服务之前检查大小以查看是否需要运行更多任务(如原始的gcmtasksservice
code)
尽管这是一个解决方案,但它不是未来的证明,因为
gcmtasksservice
上的代码可能会在未来的Google Play services版本上发生根本性的变化,在这种情况下,它可能会破坏此功能(不太可能,但可能).因此,为了安全起见,我想我还是使用AlarmManager
。从TaskService的onRunTask启动您自己的服务怎么样?
跛脚,但可能是最安全的…或者?这并没有真正回答我的问题,我已经阅读了该链接,而且3分钟的事情是保持唤醒锁的最长时间,而不是任务将运行的时间。在我的情况下,任务立即“完成”(结果立即从
onRunTask()
方法返回),因为大多数东西都是异步运行的(正如我已经解释过的)@Franco为什么要在服务中运行异步?服务已经在分离的线程中运行,因此您可以同步运行任务。此外,如果您异步运行,您也不会得到实际结果,即您的任务正在成功运行或被重新调度。是的,我知道@Randyka,但是我无法同步运行任务,因为我使用的库只允许将任务与回调同步,例如,其中一个任务是连接到Google Play services客户端,这无法同步完成:/
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;
}