如果 Android 服务被多次启动会发生什么?

如果我有以下代码:

Intent intent = new Intent(this,DownloadService.class);
for(int i=0;i<filesArray.length;i++){
startService(intent);
}

在这段代码中,DownloadService扩展了 IntentService

所以现在当我调用 startService(intent)的时候,是意味着每次调用 startService(intent)的时候我都要启动一个新的服务,还是意味着 DownloadService只运行一次,然后每次我调用 startService(intent)的时候它只是用一个不同的 startId 传递一个不同的意图。

这说得通吗? 哪一个是真的?

58183 次浏览

服务将只在一个实例中运行。但是,每次启动服务时,都会调用 onStartCommand()方法。

这是记录在案的 给你

完全正确。 只为应用程序进程创建一个 Service 实例。 当您再次调用 StartService();时,只有 onStartCommand()被调用,并且新的意图被传递给 onStartCommand()方法。

注意: onCreate()不再调用。

关于多次拨打 bindService():

当您多次调用 bindService()时,同样只有一个实例用于 Service,Android Runtime 将相同的 IBinder 对象返回给客户端。

也就是说,不会多次调用 onBind(),而只是返回缓存的 IBinder 对象。

给上面的答案添加一些更多的信息,可能对其他人有帮助: onStartCommand()方法接收的 startId对于每个 startService()调用都是不同的。

另外,如果我们像上面提到的那样编写 for 循环,那么用 onHandleIntent()编写的代码将按照 for 循环频率的定义执行很多次,但是是按顺序执行的,而不是并行执行的。

这个概念是 IntentService创建一个工作队列,每个对 startService()的请求触发 onStartCommand()onStartCommand()将意图存储在工作队列中,然后将意图一个接一个地传递给 onHandleIntent()

根据 医生:

StartService ()方法立即返回,Android 系统调用服务的 onStartCommand ()方法。如果服务尚未运行,系统首先调用 onCreate () ,然后调用 onStartCommand ()。

还有

启动服务的多个请求会导致对服务的 onStartCommand ()的多个对应调用。但是,只需要一个停止服务的请求(使用 stopSelf ()或 stopService ())即可停止该服务。

来自 Android 官方文档的非常有用的评论:

(由我加亮)

如果您的服务并发地处理对 onStartCommand()多个请求,那么当您完成处理启动请求 因为您可能已经收到了一个新的开始请求(在第一个请求结束时停止将终止第二个请求)时,您将 不应该停止服务。为了避免这个问题,可以使用 stopSelf(int)来确保停止服务的请求始终基于最近的启动请求。也就是说,当您调用 stopSelf(int)时,您将调用与您的停止请求相对应的启动请求(传递给 onStartCommand()StartId)的 把身份证给我。然后,如果服务在您能够调用 stopSelf (int)之前接收到一个新的启动请求,则 身份不匹配,服务没有停止。