O que acontece se um serviço Android for iniciado várias vezes?


120

Se eu tiver o seguinte código:

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

Neste código DownloadServiceestende IntentService.

Então, agora, quando estou chamando startService(intent), isso significa que estou iniciando um novo serviço toda vez que startService(intent)é chamado ou significa que DownloadServiceé executado uma vez e, a cada vez que o chamo startService(intent), passará um intent diferente com um startId diferente.

Isso faz sentido, e qual é o caso?

Respostas:


167

O serviço será executado apenas em uma instância. No entanto, toda vez que você inicia o serviço, o onStartCommand()método é chamado.

Isso está documentado aqui


1
Obrigado. Ele também diz: "O método startService () retorna imediatamente e o sistema Android chama o método onStartCommand () do serviço. Se o serviço ainda não estiver em execução, o sistema primeiro chama onCreate () e, em seguida, chama onStartCommand ()." Portanto, se o serviço já estiver em execução, o sistema pulará o método onCreate () e chamará apenas onStartCommand () ou o quê?
bytebiscuit

Na verdade não sei, mas tenho quase certeza que é o caso (faz muito sentido não ligar onCreate()se o serviço já estiver criado). Deve ser fácil determinar se você colocou um Log.i()em ambos os callbacks e verificou o LogCat.
Philipp Wendt

Simplesmente fiz isso ... e estranhamente ele inicia o onCreate após a última chamada startService () !!!
bytebiscuit

15
Isso porque startService()é assíncrono. Portanto, enquanto você está fazendo o loop das chamadas, o serviço em si não obteve nenhum recurso e ainda não foi iniciado.
Philipp Wendt

1
@neelabh não "imediatamente", leva algum tempo para iniciar o serviço, e o loop "for" ainda estaria em execução e chamando o serviço novamente e novamente, então as primeiras tentativas não encontrariam nenhum serviço em execução ainda ... portanto, o método startService () seria chamado algumas vezes, até que a inicialização do serviço fosse concluída. Por favor, desculpe meu inglês ruim.
mzalazar,

21

Absolutamente correto. Apenas uma instância de serviço é criada para um processo de aplicativo. E quando você chama StartService();novamente, então apenas onStartCommand()é chamado e um novo Intent é passado para o onStartCommand()método.

Nota: onCreate() não é chamado novamente.

Sobre ligar bindService()várias vezes:

Quando você chama bindService()várias vezes, novamente apenas uma instância é usada para o serviço e o Android Runtime retorna o mesmo objeto IBinder para o cliente.

Significa, onBind()não é chamado várias vezes. E apenas o objeto IBinder em cache é retornado.


Tem onStop()que ser chamado para cada correspondente onStartCommand?
IgorGanapolsky 01 de

6
@IgorGanapolsky: Em primeiro lugar, não existe esse método de retorno de chamada onStop () em Service. Precisamos chamar stopService () ou stopSelf () para interromper um serviço. E quando onStartCommand () foi chamado várias vezes para vários intents, precisamos chamar apenas stopSelf () ou stopService () apenas uma vez. Se estiver usando IntentService, você deve chamar stopSelfResult (int id) passando a id de início da solicitação de onHandleIntent (), que interromperá a solicitação de id de início correspondente, que foi colocada na fila de trabalho de IntentService. Espero que isto ajude.
Anish Mittal

8

Adicionando mais algumas informações às respostas acima, o que pode ser útil para outras pessoas, é startIdque o onStartCommand()método recebido é diferente para cada startService()chamada.

Além disso, se escrevermos no loop for conforme mencionado acima, o código escrito onHandleIntent()seria executado tantas vezes conforme definido pela frequência do loop for, mas em sequência e não em paralelo.

O conceito é IntentServicecriar uma fila de trabalho e cada solicitação de startService()acionamento onStartCommand()que, por sua vez, armazena o intent na fila de trabalho e, em seguida, passa o intent um por um para onHandleIntent().


2

De acordo com o doc :

O método startService () retorna imediatamente e o sistema Android chama o método onStartCommand () do serviço. Se o serviço ainda não estiver em execução, o sistema primeiro chama onCreate () e, em seguida, chama onStartCommand ().

e

Várias solicitações para iniciar o serviço resultam em várias chamadas correspondentes para onStartCommand () do serviço. No entanto, apenas uma solicitação para interromper o serviço (com stopSelf () ou stopService ()) é necessária para interrompê-lo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.