2011-11-05 21 views
86

Si tengo el siguiente código:¿Qué sucede si un servicio se inicia varias veces?

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

En este código se extiende DownloadServiceIntentService.

Así que ahora cuando estoy llamando startService(intent) ¿quiere decir que estoy empezando un nuevo servicio cada vez que se llama startService(intent) o ¿quiere decir que DownloadService se ejecuta una vez y luego cada vez que llamo startService(intent) se acaba de aprobar una diferente intento con un ID de inicio diferente.

¿Tiene esto sentido, y cuál de estos es el caso?

Respuesta

123

El servicio solo se ejecutará en una instancia. Sin embargo, cada vez que inicie el servicio, se llama al método onStartCommand().

Esto está documentado here

+1

Gracias. También dice allí: "El método startService() regresa inmediatamente y el sistema Android llama al método onStartCommand() del servicio. Si el servicio no se está ejecutando, el sistema llama primero aCreate(), luego llama a StartAdmand()." Entonces, si el servicio ya se está ejecutando, el sistema omitirá el método onCreate() y llamará solo a OnStartCommand() o qué? – bytebiscuit

+0

Realmente no lo sé, pero estoy bastante seguro de que ese es el caso (tiene mucho sentido de no llamar a 'onCreate()' si el servicio ya está creado). Debería ser fácil determinar si coloca 'Log.i()' en ambas devoluciones de llamada y verifica el LogCat. –

+0

Acabo de hacer eso ... y, curiosamente, inicia el onCreate después de la última llamada startService() !!! – bytebiscuit

7

absolutamente correcto. Solo se crea una instancia de servicio para un proceso de solicitud. Y cuando llamas a Start(); nuevamente, solo se llama a OnStartCommand() y se transfiere el nuevo Intent al método onStartCommand().

Nota: onCreate() no se vuelve a llamar.

en llamar bindService (varias veces):

Cuando se llama a bindService (varias veces), luego otra vez sólo una instancia se utiliza para el servicio y el tiempo de ejecución de Android regresa mismo objeto IBinder al cliente.

Medios, onBind() no se llama varias veces. Y solo se devuelve el objeto IBinder en caché.

+0

¿Se debe invocar 'onStop()' para cada 'onStartCommand' correspondiente? –

+6

@IgorGanapolsky: Antes que nada, no hay tal método de devolución de llamada onStop() en el Servicio. Necesitamos llamar a stopService() o stopSelf() para detener un servicio. Y cuando el comando onStartCommand() ha sido llamado varias veces para múltiples intentos, entonces necesitamos llamar solo a stopSelf() o stopService() solo una vez. Si usa IntentService, debe llamar a stopSelfResult (int id) que pasa el id de inicio de la solicitud de onHandleIntent(), que detendrá la solicitud de id de inicio correspondiente, que se colocó en la cola de trabajos de IntentService. Espero que esto ayude. –

2

Agregar más información a las respuestas anteriores que puede ser útil para otros es que, startId que el método onStartCommand() recibe es diferente para cada llamada a startService(). Además, si escribimos en for loop como se menciona arriba, el código escrito enHandleIntent() se ejecutará tantas veces como lo defina la frecuencia for loop pero en secuencia y no en paralelo. El concepto es IntentService crea una cola de trabajo y cada solicitud para iniciarService() activa onStartCommand() que a su vez almacena el intento en la cola de trabajo y luego pasa el intento uno por uno a onHandleIntent().

Cuestiones relacionadas