2012-05-18 15 views
7

Después de leer la mayoría de la documentación disponible sobre los servicios de Android en el sitio del desarrollador y aquí en stackoverflow, todavía estoy confundido por varios aspectos de ejecutar un servicio en una tarea separada. Con suerte, alguien puede ponerme en el camino correcto.Cómo iniciar una tarea en segundo plano en el servicio Android

Digamos que tenemos marco de servicios trivial como

public class HliService extends Service { 

    @Override 
    public void onCreate() { 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     // If we get killed, after returning from here, restart 
     return START_STICKY; 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // We don't provide binding, so return null 
     return null; 
    } 

    @Override 
    public void onDestroy() { 
    } 
} 

y en el manifiesto, tengo

<service android:name=".HliService" android:process=":HLI_Comms"/> 

para que el servicio se ejecuta en su propio hilo.

La intención del servicio es proporcionar una tarea en segundo plano que comunique a un dispositivo usando un socket TCP y haga otras cosas. A riesgo de ignorar problemas con la batería, etc., básicamente me gustaría que se ejecutara para siempre.

Algo así como

// Method that communicates using a TCP socket, and needs to send 
// information back to the activity and receive messages from activity 
// not shown here. 
private void dummytask() { 

    boolean keepGoing = true; 
    while (keepGoing) { 
     // do useful stuff in here 
     // sets keepGoing false at some point 
    } 
    stopSelf(); 
} 

¿Cuál es la mejor manera de iniciar este método/tarea?

He examinado el código en el sitio del desarrollador que usa un manejador de mensajes y un looper, que solo entiendo parcialmente, pero parece muy complicado y tal vez más de lo que necesito.

No creo que pueda llamar a este método desde onCreate() o onStartCommand() ya que ninguno de los dos completaría cuando se invoque desde el sistema? ¿Debo comenzar con un temporizador o alarma?

Necesitaré agregar un manejador de mensajes para comunicarme con la actividad de la interfaz gráfica de usuario, pero dado que estoy comenzando el servicio en otra cadena (en virtud de la instrucción manifiesta de "proceso"), ¿necesito usar AIDL en su lugar? ?

También he considerado el uso de AysnchTask en lugar de extender el servicio, pero parece ser más adecuado para ejecutar una tarea y luego terminar.

+0

'while (keepGoing)' - si está en otro hilo que el que establece 'keepGoing' en falso' keepGoing' DEBE SER 'volátil' - lea en el modelo de memoria Java –

+0

Consulte esta respuesta, esto puede ayudarlo . [ENTER Descripción enlace aquí] [1] [1]: http://stackoverflow.com/a/13783477/2165080 –

Respuesta

2

para que el servicio se ejecute en su propio hilo.

Eso pone el servicio en su propio proceso. Esto generalmente es algo que debe evitarse, ya que consume RAM y CPU adicionales (para IPC). Puede crear un hilo simplemente creando un Thread o cualquier cantidad de otros medios, la mayoría de los cuales han estado en Java durante una década más o menos.

A riesgo de ignorar problemas de batería, etc., básicamente me gustaría que funcione para siempre.

Es prácticamente imposible que un servicio funcione para siempre. Los usuarios o el SO se desharán de su servicio eventualmente.

¿Cuál es la mejor manera de iniciar este método/tarea?

Llamada dummytask() desde un hilo de fondo.

¿Debo usar AIDL?

No. Su servicio puede difundir un Intent, o invocar una PendingIntent suministrada por la actividad, o enviar un Message a través de un Messenger suministrada por la actividad, etc. La mejor sería utilizar el LocalBroadcastManager del androide de la ayuda paquete, pero eso no funcionará a través de los límites del proceso, lo que le obliga a opciones de comunicación más costosas.

+0

Ok - gracias @CommonsWare. También analicé ese método, pero también estoy inseguro sobre ciertos aspectos de su implementación: haré más investigación y quizás publique una pregunta de seguimiento. Tomaré su consejo sobre no usar el "proceso". Por cierto, sé que el servicio no funcionará para siempre, fue solo una simplificación. Gracias de nuevo. – SteveJP

+0

@CommonsWare Gracias por la explicación anterior ... realmente buena – Biplab

0

Creo que podría utilizar un IntentService que ejecuta configurando una alarma (normal) (AlarmManager.setRepeating) con un PendingIntent en ella. Puedes notificar a la UI transmitiendo un Intent desde el IntentService y recibiéndolo en tu UI a través de BroadcastReceiver.

+0

Gracias @omoling: ¿No es más adecuado para ejecutar una tarea pequeña y luego terminar, en lugar de iniciar un proceso de larga ejecución? – SteveJP

Cuestiones relacionadas