Por favor, explique algunos conceptos de servicio de Android

Acabo de acercarme a los Servicios de Android, pero tengo muchas dudas. Aquí hay algunas preguntas. Antes de empezar, tenga en cuenta que he leído las páginas Android Services (oficial) Bounded Services (official) plus sone Teoría de las clases internas en mi idioma. Por favor sea paciente, todavía estoy un poco confundido.

1) En primer lugar, un Servicios se diferencia de un AsyncTask principalmente porque continúa ejecutándose también si la aplicación está pausada (es decir, el usuario está viendo otra aplicación); AsyncTask se detiene en esos casos. ¿Está bien o estoy equivocado? 2) Un servicio se ejecuta en el mismo subproceso de la actividad que lo inició a través de startService (). Para no afectar las actuaciones de la actividad, tengo que crear un hilo separado para ese servicio, por ejemplo implementando la interfaz Runnable. Otro método es hacer un servicio que extienda IntentService, que automáticamente proporciona un nuevo subproceso para el servicio: se crea un nuevo subproceso en cualquier llamada onHandleIntent ().

Ahora, veamos mi problema concreto. Necesito crear un Servicio que será utilizado por muchas Actividades: su tarea será conectarse al servidor DB cada 60 segundos y buscar noticias. Si se encuentra una noticia, notifique que hay nuevas noticias (si estamos en MainActivity) o muestra el nuevo título de las noticias (si estamos en el lector de noticias). ¿Cómo debo codificarlo? He hecho una MainActivity que instancia un NewsService y llama inmediatamente a startService (). En el otro lado, tengo el NewsService se extiende IntentService, que (crea un nuevo hilo cuando se llama onHandleIntent?) Y busca nuevas noticias. ¿Es una mala idea usar un IntentService? Me di cuenta de que será muy feo iniciar el servicio llamando startService () indefinidamente. Al comienzo de este ejercicio creí que era una buena solución porque automáticamente crea un nuevo hilo y facilita la implementación del Servicio. Pero ahora tengo algunas dudas (no puedo saber si hay noticias, ¿cómo puede saber MainActivity y cómo obtener el título)

Esto se debe hacer con una clase Thread normal, que hace un ciclo infinito en su método run (), revisando noticias cada 60 segundos y, si hay una nueva, lee el título desde el DB remoto y actualiza las actividades de botones / vistas. A continuación, si la aplicación se cierra por el usuario, el servicio también se cerrará. Pero el problema es que si la clase es tal, su trabajo se detendrá cuando la Actividad Principal se detiene o se detiene, y otras Actividades (el Lector de Noticias en este caso) no pueden obtener ninguna actualización porque el nuevo hilo no está recibiendo noticias en este momento. Así que necesito un servicio.

Espero que esté claro. ¿Cómo debo implementar una solución de la manera correcta? Por favor, destaque todo mal en mi texto, realmente necesito aprender: D

Parece que has entendido todo correctamente.

En cuanto a su problema específico, recomiendo lo siguiente:

  • Utilice AlarmManager para programar su servicio. No deje que el Service ejecute cuando no tiene que hacerlo.

  • Utilice una Broadcast Intent para obtener nuevas noticias. Todas las Activities tendrán que tener un BroadcastReceiver interno que escuche la intención de Broadcast del servicio y reaccione en consecuencia.

Los servicios son un buen enfoque para lo que quieres, son bastante buenos para hacer procesos que consumen pocos recursos como mantener un daemon en segundo plano, también son buenos para mostrar notificaciones sin actividad y seguir funcionando incluso si sale de la actividad.

Cuando necesite realizar operaciones más pesadas en su servicio, puede usar AsyncTask , iniciarlo, ejecutar su operación en otro subproceso y recibir automáticamente el resultado en su subproceso principal.

Si desea mantener el servicio siempre en ejecución, puede utilizar START_STICKY en su Servicio

  @Override public int onStartCommand(final Intent intent, final int flags, final int startId) { // Ensure the service will restart if it dies return START_STICKY; } 

Y puede iniciar el servicio haciendo:

 final Intent service = new Intent(); service.setComponent(new ComponentName(YourService.PACKAGE_NAME, YourService.SERVICE_FULL_NAME)); // Start the service context.startService(service); 

1) En primer lugar, un Servicios se diferencia de un AsyncTask principalmente porque continúa ejecutándose también si la aplicación está pausada (es decir, el usuario está viendo otra aplicación); AsyncTask se detiene en esos casos. ¿Está bien o estoy equivocado?

Esto no es correcto. AsyncTask es un mecanismo para descargar el procesamiento de fondo en un hilo separado y proporciona un mecanismo para informar al usuario del progreso, error y finalización de ese procesamiento en segundo plano. AsyncTask no deja de funcionar si la aplicación está en pausa. Continúa realizando su procesamiento en segundo plano. En general, existe un acoplamiento estrecho entre un AsyncTask y la Activity que lo inició.

Un Service , por otro lado, está (generalmente) completamente desacoplado de la Activity que lo inició. Un Service tiene su propio ciclo de vida que es independiente de las otras actividades de la aplicación. Además, los servicios no tienen UI, por lo que no están vinculados a los elementos visuales de la aplicación y no proporcionan mecanismos (directos) para la retroalimentación visual relacionada con el progreso, error o terminación. Esto necesita ser programado por separado.

2) Un servicio se ejecuta en el mismo subproceso de la actividad que lo inició a través de startService (). Para no afectar las actuaciones de la actividad, tengo que crear un hilo separado para ese servicio, por ejemplo implementando la interfaz Runnable. Otro método es hacer un servicio que extienda IntentService, que automáticamente proporciona un nuevo subproceso para el servicio: se crea un nuevo subproceso en cualquier llamada onHandleIntent ().

Esto tampoco es correcto. Un Service no se ejecuta en ningún subproceso específico. Los métodos de ciclo de vida de un Service ( onCreate() , onStartCommand() , etc.) se ejecutan en el subproceso principal (UI), que puede o no ser el mismo subproceso que se llama startService() . Sin embargo, un Service puede (y normalmente lo hace) iniciar otros hilos de fondo, tantos como sea necesario, para realizar el trabajo necesario.

IntentService es un tipo específico de Service que gestiona uno o más subprocesos de trabajo que utiliza para realizar el procesamiento en segundo plano. Usted envía un "comando" a un IntentService y el IntentService entonces pone su comando en una cola. En algún momento (diferentes implementaciones en diferentes versiones de Android se comportan de manera diferente), su "comando" se deshace y se procesa en un hilo de fondo. IntentService detiene después de que todos los "comandos" han sido procesados. IntentService no suele ser la mejor opción para un Service debido a la forma en que se comporta.


IntentService definitivamente no es lo que quieres en tu caso. Probablemente debería usar AlarmManager y establecer una alarma que inicie su Service cada minuto. Cuando se inicia el Service , debe crear un subproceso de fondo que contacta con su servidor y comprueba si hay noticias. Si no hay noticias, puede desaparecer. Si hay nuevas noticias, puede iniciar su Activity para informar al usuario, o puede enviar una Intent difusión que verá su Activity (si está en ejecución), o podría crear una Notification que el usuario pueda abrir cuando quiere. Debe averiguar cómo desea determinar cuándo la aplicación debe dejar de comprobar el servidor. Tal vez el usuario debe decirle que ya no le interesa, o tal vez el Service puede reconocer que la aplicación ya no se está ejecutando (o no se ha visto en más de X horas o lo que sea). Hay muchas maneras de hacer esto y depende de sus requisitos.

  • BroadcastReceiver cuando se cambia el estado de la red wifi o 3g
  • Captura de notificaciones de otras aplicaciones
  • ¿Por qué mis intenciones no se entregan correctamente?
  • Android: ¿Cómo solucionar la falla de la conexión de la API de Google desde un servicio?
  • Android Fatal señal 11 (SIGSEGV) en 0x636f7d89 (código = 1). ¿Cómo se puede localizar?
  • OnServiceConnected () no se llama
  • ¿Qué significa android: enabled para un servicio?
  • Las siguientes llamadas onBind () no se activan
  • El servicio de Android no se reinicia en lollipop
  • Varias TextViews se actualizan muy lentamente
  • Sincronización de un servicio REST con una aplicación de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.