Vinculación / desvinculación a un servicio en una aplicación

Tengo una aplicación de Android que se vincula a un servicio persistente (una vez iniciado con startService() ).

El servicio es una parte integral de la aplicación y por lo tanto se utiliza en casi todas las actividades. Por lo tanto, quiero enlazar al servicio sólo una vez (en lugar de enlazar / desvincular en cada actividad) y mantener el enlace durante la vida de mi aplicación.

He extendido desde la aplicación y enlazar con el servicio en la aplicación # onCreate () . Sin embargo ahora tengo el problema que no sé cuando mi aplicación existe ya que la aplicación # onTerminate () nunca se llama, vea JavaDoc:

Este método se utiliza en entornos de procesos emulados. Nunca se llamará a un dispositivo Android de producción, donde los procesos se eliminan simplemente matándolos; No se ejecuta ningún código de usuario (incluida esta devolución de llamada) al hacerlo.

Entonces, ¿cómo puedo limpiar de forma limpia de un servicio enlazado en la aplicación?

He resuelto este problema contando las referencias a la vinculación de servicios en la Application . Cada Activity tiene que llamar a acquireBinding() en sus métodos onCreate() y llamar a releaseBinding() en onDestroy() . Si el contador de referencia llega a cero, se libera la unión.

He aquí un ejemplo:

 class MyApp extends Application { private final AtomicInteger refCount = new AtomicInteger(); private Binding binding; @Override public void onCreate() { // create service binding here } public Binding acquireBinding() { refCount.incrementAndGet(); return binding; } public void releaseBinding() { if (refCount.get() == 0 || refCount.decrementAndGet() == 0) { // release binding } } } // Base Activity for all other Activities abstract class MyBaseActivity extend Activity { protected MyApp app; protected Binding binding; @Override public void onCreate(Bundle savedBundleState) { super.onCreate(savedBundleState); this.app = (MyApp) getApplication(); this.binding = this.app.acquireBinding(); } @Override public void onDestroy() { super.onDestroy(); this.app.releaseBinding(); } } 

De la respuesta de Sven:

He resuelto este problema contando las referencias a la vinculación de servicios en la aplicación. Cada actividad tiene que llamar a acquireBinding () en sus métodos onCreate () y llamar a releaseBinding () en onDestroy (). Si el contador de referencia llega a cero, se libera la unión.

Estoy de acuerdo, pero usted no debe hacerlo en onDestroy – que a menudo no se llama.

En su lugar, sugiero lo siguiente (basado en su ejemplo de código) …

 // Base Activity for all other Activities abstract class MyBaseActivity extend Activity { protected MyApp app; protected Binding binding; @Override public void onCreate(Bundle savedBundleState) { super.onCreate(savedBundleState); this.app = (MyApp) getApplication(); this.binding = this.app.acquireBinding(); } @Override protected void onPause() { super.onPause(); // Pre-HC, activity is killable after this. if ((11 > Build.VERSION.SDK_INT) && (isFinishing())) onFinishing(); } @Override protected void onStop() { super.onStop(); if ((10 < Build.VERSION.SDK_INT) && (isFinishing())) onFinishing(); } protected void onFinishing() { // Do all activity clean-up here. this.app.releaseBinding(); } } 

PERO, mi uso de isFinishing () es sólo un pensamiento – no estoy seguro de que sea fiable. Tal vez onPause / onStop se llama con isFinishing () false, pero luego la actividad se mata – y su releaseBinding () nunca se llama.

Si te deshaces del cheque isFinishing creo que necesitas mover la llamada de acquireBinding () de onCreate a onStart / onResume (dependiendo de la versión de sdk), para asegurarte de que tu cuenta de ref no sea desordenada.

¿Quién sabía que liberar el servicio de su aplicación sería tan complicado?

¿Es obligatorio desenrollar en este caso? La aplicación se mata de todos modos. Intenté implementar una aplicación de ejemplo haciendo esto sin desenlazar y parece funcionar correctamente.

  • Cómo enviar el mensaje del servicio a la actividad
  • Cómo solicitar un IntentService para obtener información sobre su cola
  • No se puede comprobar si AlarmManager ha configurado la alarma
  • Mantener el servicio de fondo vivo después de la aplicación de salida del usuario
  • La notificación sigue en la barra después de matar al servicio
  • Uso de Dagger 2 para inyectar en servicio
  • Diálogo de alerta del servicio de Android
  • Registrador de clave de Android
  • No recibe devoluciones de llamada CountDownTimer en Service
  • Servicio de Android matado
  • Servicio android onBind SecurityException
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.