GcmTaskService 运行 可以异步任务吗?
Can GcmTaskService run async tasks?
我需要 运行 在 Android 应用程序的后台定期执行网络任务。
我最初打算使用 AlarmManager
(不能使用 JobScheduler
因为它必须在棒棒糖之前的设备上工作),但后来我遇到了 GcmNetworkManager
这似乎更容易使用并提供更简单的 API,并且如果设备连接到互联网,它会处理 运行ning 任务(也不需要使用广播接收器,所以更少classes 维护)。
我遇到的问题是我需要 运行 的任务由 3 个异步步骤组成,GcmTaskService
似乎是为 运行 同步任务创建的。
我已经对此进行了测试,发现我的异步任务 运行 在 GcmTaskService
中结束之前都很好(我的服务然后自行停止),但是我担心这可能是更多的是巧合,因为我的异步任务非常快,而不是服务没有在 GcmTaskService
代码中停止的事实(我试图查看代码,但它被混淆了所以很难理解它是什么确实)。
有谁知道 GcmTaskService
实际上是 运行 直到扩展 class 停止它或者它是否会在同步任务结束时停止?
GcmTaskService
只运行你的任务3分钟,3分钟后算超时。因此,如果您有大型任务,我建议您创建自己的服务。
关于 GcmTaskService
的更多信息:read this
经过一些调查和调试,我找到了答案。我会在这里描述它,以便将来它可以帮助其他人。
正如我所怀疑的那样,当 运行 需要的所有任务都完成时,GcmTaskService
会自行停止(这很有意义)。对此的证明是在这个方法上(在 GcmTaskService
class 内):
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()
returns 之后从 运行 执行任务的线程调用。
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
而不是为了安全起见。
从 TaskService 的 onRunTask 启动您自己的服务如何?
蹩脚,但可能是最安全的......或者?
我需要 运行 在 Android 应用程序的后台定期执行网络任务。
我最初打算使用 AlarmManager
(不能使用 JobScheduler
因为它必须在棒棒糖之前的设备上工作),但后来我遇到了 GcmNetworkManager
这似乎更容易使用并提供更简单的 API,并且如果设备连接到互联网,它会处理 运行ning 任务(也不需要使用广播接收器,所以更少classes 维护)。
我遇到的问题是我需要 运行 的任务由 3 个异步步骤组成,GcmTaskService
似乎是为 运行 同步任务创建的。
我已经对此进行了测试,发现我的异步任务 运行 在 GcmTaskService
中结束之前都很好(我的服务然后自行停止),但是我担心这可能是更多的是巧合,因为我的异步任务非常快,而不是服务没有在 GcmTaskService
代码中停止的事实(我试图查看代码,但它被混淆了所以很难理解它是什么确实)。
有谁知道 GcmTaskService
实际上是 运行 直到扩展 class 停止它或者它是否会在同步任务结束时停止?
GcmTaskService
只运行你的任务3分钟,3分钟后算超时。因此,如果您有大型任务,我建议您创建自己的服务。
关于 GcmTaskService
的更多信息:read this
经过一些调查和调试,我找到了答案。我会在这里描述它,以便将来它可以帮助其他人。
正如我所怀疑的那样,当 运行 需要的所有任务都完成时,GcmTaskService
会自行停止(这很有意义)。对此的证明是在这个方法上(在 GcmTaskService
class 内):
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()
returns 之后从 运行 执行任务的线程调用。
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
而不是为了安全起见。
从 TaskService 的 onRunTask 启动您自己的服务如何? 蹩脚,但可能是最安全的......或者?