2010-05-05 20 views
5

Utilicé IntentService en mi código en lugar de Service porque IntentService crea un hilo para mí en onHandleIntent (intento de intención), así que no tengo que crear un Thead en el código de mi servicio.Comportamiento inesperado de IntentService

Esperaba que dos intenciones al mismo IntentSerivce se ejecutarán en paralelo porque se genera un hilo en IntentService para cada invención. Pero mi código resultó que los dos intentos se ejecutaron de forma secuencial.

Este es mi código IntentService:

public class UpdateService extends IntentService { 

    public static final String TAG = "HelloTestIntentService"; 

    public UpdateService() { 
     super("News UpdateService"); 
    } 

    protected void onHandleIntent(Intent intent) { 

     String userAction = intent 
     .getStringExtra("userAction"); 

     Log.v(TAG, "" + new Date() + ", In onHandleIntent for userAction = " + userAction + ", thread id = " + Thread.currentThread().getId()); 

     if ("1".equals(userAction)) { 
      try { 
       Thread.sleep(20 * 1000); 
      } catch (InterruptedException e) { 
       Log.e(TAG, "error", e); 
      } 

      Log.v(TAG, "" + new Date() + ", This thread is waked up."); 
     } 
    } 
} 

Y el llamado código de servicio es el siguiente:

public class HelloTest extends Activity { 

    //@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.main); 

     Intent selectIntent = new Intent(this, UpdateService.class); 
     selectIntent.putExtra("userAction", 
       "1"); 

     this.startService(selectIntent); 

     selectIntent = new Intent(this, UpdateService.class); 
     selectIntent.putExtra("userAction", 
       "2"); 

     this.startService(selectIntent); 

    } 
} 

vi este mensaje de registro en el registro:

V/HelloTestIntentService( 848): Wed May 05 14:59:37 PDT 2010, In onHandleIntent for userAction = 1, thread id = 8 
D/dalvikvm( 609): GC freed 941 objects/55672 bytes in 99ms 
V/HelloTestIntentService( 848): Wed May 05 15:00:00 PDT 2010, This thread is waked up. 
V/HelloTestIntentService( 848): Wed May 05 15:00:00 PDT 2010, In onHandleIntent for userAction = 2, thread id = 8 
I/ActivityManager( 568): Stopping service: com.example.android/.UpdateService 

El el registro muestra que el segundo intento esperó el primer intento de finalizar y están en el mismo hilo.

Hay algo que malinterpreté de IntentService. Para hacer que dos intentos de servicio se ejecuten en paralelo, ¿tengo que reemplazar IntentService por el servicio e iniciar un hilo yo mismo en el código de servicio?

Gracias.

Respuesta

6

Hasta donde yo sé, The IntentService tiene un hilo de controlador, y cada intención colas en ese hilo. Cuando finalizan todos los intentos en cola, el servicio finaliza. No crea hilos independientes por intento. No sé de ninguna subclase de servicio que funcione de la manera que usted describe, probablemente tenga que escribir la suya propia.

+3

El patrón de diseño de IntentService es una cola de trabajos que garantiza que las solicitudes se pongan en cola y no se procesen en paralelo. Como se señala a continuación, puede disparar una AsyncTask para cada trabajo paralelo. Asegúrese de que su código de servicio sea reentrante. – mobibob

9

La cola de intención es el objetivo de usar IntentService.

1

Creo que lo que quiere es una AsyncTask en lugar de un Servicio o un Servicio de Intento. O siempre se puede simplemente disparar desde la cadera mediante la definición de un ejecutable como esto:

Runnable runnable = new Runnable() { 

    public void run() { 
     .... 
    } 
}; 
new Thread(runnable).start(); 

... para cada una de sus tareas. Honestamente, eso puede ser más fácil que lidiar con estas clases de ayuda de Android.

+0

Usaría AsyncTask en Runnable, definitivamente ayuda con el procesamiento previo/posterior y la obtención de resultados de nuevo en el hilo de UI. Si algo puede durar más que la duración de la actividad, entonces usar IntentService es el camino a seguir. – DustinB

+0

AsyncTask es bueno, pero debe usarse en un Servicio, siempre debe tener en cuenta el ciclo de vida de Android: las actividades se destruyen y vuelven a crear durante los cambios de configuración ... una AsyncTask perderá referencia a la Actividad y podría destruirse ... –

7

Todas las solicitudes a IntentService se manejan en un único hilo de trabajo, y solo se procesará una solicitud a la vez. Si desea realizar dos tareas en paralelo, creo que debe utilizar el Servicio y crear subprocesos para cada tarea después de que se inicie el Servicio.

En cuanto a AsyncTask, hay un grupo de subprocesos para manejar todas las tareas. Si su número de tarea excede el tamaño del grupo de subprocesos, algunas de estas AsyncTasks necesitarán esperar hasta que un subproceso del grupo esté disponible. Sin embargo, el tamaño del grupo de subprocesos cambia en diferentes versiones de plataforma.

aquí está mi resultado de la prueba:

  • Android 2.2: Tamaño del grupo de subprocesos = 5
  • Android 1.5: Tamaño del grupo de subprocesos = 1
+0

Gracias por la agradable breve explicación. realmente ayuda – bschandramohan

Cuestiones relacionadas