Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android GcmTaskService能否运行异步任务?_Android_Google Play Services - Fatal编程技术网

Android GcmTaskService能否运行异步任务?

Android GcmTaskService能否运行异步任务?,android,google-play-services,Android,Google Play Services,我需要在Android应用程序的后台定期运行网络任务 我最初打算使用AlarmManager(不能使用JobScheduler,因为它必须在棒棒糖前的设备上工作),但后来我遇到了GcmNetworkManager,它似乎更易于使用,并提供了更简单的API,如果设备连接到internet,它负责运行任务(也不需要使用广播接收器,因此需要维护的类更少) 我遇到的问题是,我需要运行的任务由3个异步步骤组成,gcmtasksservice似乎是为了运行同步任务而创建的 我已经对此进行了测试,发现我的异步

我需要在Android应用程序的后台定期运行网络任务

我最初打算使用
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;
}