GcmTaskService可以运行异步任务吗?

时间:2016-01-27 03:55:40

标签: android google-play-services

我需要在Android应用的背景上定期运行网络任务。

我最初会使用AlarmManager(不能使用JobScheduler因为它必须在棒棒糖前设备上工作),但后来我遇到了{{1}这似乎更容易使用,并提供了一个更简单的API,如果设备连接到互联网,它负责运行任务(也不需要使用广播接收器,因此维护的类更少)。

我遇到的问题是我需要运行的任务由3个异步步骤组成,而GcmNetworkManager似乎是为了运行同步任务而创建的。

我已对此进行了测试,发现我的异步任务运行得很好,直到GcmTaskService内部结束(我的服务随后停止),但是我担心这可能更巧合,因为我的异步任务非常快,而不是服务没有在GcmTaskService代码中停止的事实(我试图查看代码,但是它被混淆了所以它很难理解它是什么一样)。

有人知道GcmTaskService实际上是否会在扩展类停止它之前运行,或者在同步任务结束时它是否会被停止?

3 个答案:

答案 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分钟,之后计为超时。因此,如果您有大尺寸任务,我建议您创建自己的服务 有关GcmTaskServiceread this

的更多信息

答案 2 :(得分:0)

从TaskService的onRunTask开始自己的服务怎么样? 瘸子,但可能最安全......或者?