Una forma más eficiente de actualizar la interfaz de usuario del servicio que las intenciones?

Tengo actualmente un servicio en Android que es un cliente de la muestra VOIP así que escucha hacia fuera para los mensajes de SIP y si recibe uno que pone en marcha una pantalla de la actividad con los componentes de la interfaz de usuario.

A continuación, los siguientes mensajes SIP determinan lo que la actividad debe mostrar en la pantalla. Por ejemplo, si es una llamada entrante, mostrará Responder o Rechazar o una llamada saliente mostrará una pantalla de marcación.

En el momento en que utilizo Intents para que la Actividad sepa qué estado debe mostrar.

Un ejemplo es el siguiente:


Intent i = new Intent(); i.setAction(SIPEngine.SIP_TRYING_INTENT); i.putExtra("com.net.INCOMING", true); sendBroadcast(i); Intent x = new Intent(); x.setAction(CallManager.SIP_INCOMING_CALL_INTENT); sendBroadcast(x); Log.d("INTENT SENT", "INTENT SENT INCOMING CALL AFTER PROCESSINVITE"); 

Así, la actividad tendrá un receptor de difusión registrado para estos intentos y cambiará su estado de acuerdo con la última intención que recibió.

Ejemplo de código como sigue:


  SipCallListener = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(SIPEngine.SIP_RINGING_INTENT.equals(action)){ Log.d("cda ", "Got RINGING action SIPENGINE"); ringingSetup(); } if(CallManager.SIP_INCOMING_CALL_INTENT.equals(action)){ Log.d("cda ", "Got PHONE RINGING action"); incomingCallSetup(); } } }; IntentFilter filter = new IntentFilter(CallManager.SIP_INCOMING_CALL_INTENT); filter.addAction(CallManager.SIP_RINGING_CALL_INTENT); registerReceiver(SipCallListener, filter); 

Esto funciona sin embargo, parece que no es muy eficiente, los intentos se obtendrá el sistema de difusión de ancho y Intents tener que disparar para diferentes estados parece que podría llegar a ser ineficiente cuanto más tengo que incluir, así como la adición de complejidad.

Así que me preguntaba si hay una manera diferente más eficiente y más limpio para hacer esto?

¿Hay alguna manera de mantener Intents transmitiendo solo dentro de una aplicación?

¿Las devoluciones de llamada serían una mejor idea? Si es así, ¿por qué y de qué manera deben implementarse?

2 Solutions collect form web for “Una forma más eficiente de actualizar la interfaz de usuario del servicio que las intenciones?”

ACTUALIZACIÓN 2015:

Esta pregunta / respuesta aún recibe un poco de actividad, pero es más de 5 años de edad y las cosas han cambiado un poco. Hace 5 años, la respuesta a continuación fue cómo lo habría manejado. Más tarde escribí una solución de inyección de dependencia muy ligera que estaba usando por un tiempo (que mencioné en los comentarios). Hoy en día, yo respondería a esta pregunta usando Dagger y RxAndroid. Dagger para inyectar una clase de "mediador" tanto en el Servicio como en todas las Actividades que necesitan ser notificadas, el Servicio empujaría la actualización de estado a la clase mediadora y la clase mediadora exponería un observable para las actividades para consumir la actualización de estado En lugar del receptor de radiodifusión del OP).

Respuesta original

Por lo general subclase la aplicación y dejar que mi comunicación en la aplicación pasar por esta clase (o tener un mediador propiedad de la aplicación hacer el trabajo … independientemente, la aplicación es el punto de entrada para el servicio de comunicación). Tengo un servicio obligado que necesita actualizar la interfaz de usuario también (mucho más simple que el suyo, pero la misma idea) y básicamente le dice a la aplicación su nuevo estado y la aplicación puede pasar esta información a lo largo de una manera u otra a la actual Actividad activa. También puede mantener un puntero a la actividad actualmente activa (si hay más de una) y tomar decisiones si simplemente actualizar la actividad actual, transmitir la intención de iniciar una actividad diferente, ignorar el mensaje, etc. También subclase Actividad y haga que su nueva clase base de actividad indique a la Aplicación que actualmente es la activa en onResume y que está siendo detenida en onPause (para los casos en que su servicio se está ejecutando en segundo plano y las actividades están todas detenidas).

EDITAR:

En respuesta al comentario, aquí hay más detalles.

Su aplicación actualmente consiste en clases derivadas de la actividad y derivadas del servicio en su mayor parte. Inherently, obtiene funcionalidad de una instancia de la clase android.app.Application. Esto se declara en su manifiesto (por defecto) con la siguiente línea:

 <application android:icon="@drawable/icon" android:label="@string/app_name"> 

El elemento de la aplicación en su manifiesto no utiliza el atributo android: name, por lo que sólo crea una instancia de la clase android.app.Application predeterminada para representar el contexto global de la aplicación.

En mis aplicaciones, creo una subclase de Application (ApplicationEx, por ejemplo) y le digo a mi aplicación a través del manifiesto que ésta es la clase a instanciar como MI contexto de aplicación global. Por ejemplo:

 <application android:name="com.mycompany.myapp.app.ApplicationEx" android:icon="@drawable/app_icon" android:label="@string/app_name"> 

Ahora puedo agregar métodos a ApplicationEx para actividades y servicios para usar para comunicarse. Siempre hay una única instancia de su contexto de aplicación global, por lo que este es su punto de partida si algo necesita ser global para su aplicación.

Una segunda parte de esto es que en lugar de derivar mis servicios y actividades de Servicio y Actividad, creo una subclase de cada uno con un método getAppContext que arroja el valor devuelto de getApplicationContext (que ya existe en ambas clases porque derivan de Context ) A mi clase ApplicationEx.

Asi que……..

Dicho todo esto, agrega una propiedad CurrentActivity a su clase ApplicationEx de tipo Actividad (o ActivityBase si la subclases como yo). En el método onResume de ActivityBase, se pasa a ApplicationEx para que establezca CurrentActivity en esa actividad. Ahora, puede exponer métodos en ApplicationEx para pasar información directamente a la actividad actual en lugar de depender de los mecanismos de intención.

Eso es tan claro como puedo hacerlo

Puede enviar intentos de difusión sólo a su propia aplicación y no a todo el sistema con LocalBroadcastManager :

Ayuda para registrar y enviar transmisiones de Intents a objetos locales dentro de su proceso. Esto tiene varias ventajas sobre el envío de transmisiones globales con sendBroadcast (Intent):

Sabes que los datos que estás difundiendo no dejarán tu aplicación, así que no tengas que preocuparte por la filtración de datos privados.

No es posible que otras aplicaciones envíen estas emisiones a su aplicación, por lo que no es necesario preocuparse por tener fallas de seguridad que puedan explotar.

Es más eficiente que enviar una emisión global a través del sistema.

Sin embargo, todavía recomiendo ir con el enfoque de servicio y vinculación local y hablar a través de Handler cuando sea necesario para actualizar los componentes de interfaz de usuario para la eficiencia.

  • Descubrimiento del servicio de red error de tutorial android: Servicio perdido, el teléfono se desactiva
  • ¿Es posible ejecutar mi servicio por tiempo indefinido?
  • Grabación de errores en vídeos android
  • Diseño de hilos múltiples de Android Service
  • GCM de Android SERVICE_NOT_AVAILABLE
  • La notificación de la barra de estado de Android lanza una nueva aplicación aunque esté en ejecución. ¿Cómo sincronizar la aplicación de lanzamiento desde el icono de la aplicación y la notificación de barra de estado?
  • Cómo saber si el usuario está en la pantalla de bloqueo desde el servicio
  • Android Development: Cambio del brillo de la pantalla en el servicio
  • Cómo ensayar un servicio de Android que depende de una conexión de red
  • ¿Cómo comprobar el permiso automático de MIUI mediante programación?
  • BadParcelableException: ClaseNotFoundException al unmarshalling
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.