首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GcmTaskService能运行异步任务吗?

GcmTaskService能运行异步任务吗?
EN

Stack Overflow用户
提问于 2016-01-27 03:55:40
回答 3查看 1.3K关注 0票数 3

我需要在Android应用程序的背景下定期运行一个网络任务。

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

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

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

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-01-27 22:41:56

经过一番调查和调试,我找到了答案。我会在这里描述,这样也许它能在将来帮助到其他人。

正如我所怀疑的,当所有需要运行的任务都完成(这很有意义)时,GcmTaskService就会停止运行。这个方法(在GcmTaskService类中)证明了这一点:

代码语言:javascript
复制
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()返回之后)。

var1是开发人员在创建任务时分配给它的标记,而zzaIU是该服务需要运行的任务列表。因此,正如我们所看到的,已经完成的任务将从列表中删除,如果没有剩下的要运行的任务,则服务将停止。

可能的解决方案:

但是,有一种可能的解决方案可以在GcmTaskService中运行异步任务。为此,我们需要重写onStartCommand()方法,以防止GcmTaskService在另一个线程中启动任务。

代码将如下所示:

代码语言:javascript
复制
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服务版本中发生根本性的变化,在这种情况下,它可能会破坏这一功能(不太可能,但可能)。所以,为了安全起见,我想我还是选择AlarmManager吧。

票数 3
EN

Stack Overflow用户

发布于 2016-01-27 04:26:20

GcmTaskService只运行你的任务3分钟,之后它就被计算为超时。因此,如果您有较大的任务,我建议您创建您自己的服务。

更多关于GcmTaskService阅读这篇文章的信息

票数 1
EN

Stack Overflow用户

发布于 2016-08-14 21:47:03

从TaskService的onRunTask开始自己的服务怎么样?站不住脚,但可能是最安全的...or?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35028601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档