2012-07-13 23 views
15

Estoy desarrollando una aplicación de Android usando comunicación bluetooth (usando un protocolo propetario) y necesito detectar el momento en que se mata la aplicación.La aplicación de Android no llama a "onDestroy()" cuando se mata (ICS)

Quería utilizar el método "onDestroy()" pero no se llama cada vez que se mata la aplicación. Me di cuenta de que se llama cuando presiono el botón Atrás y, solo algunas veces, cuando elimino la aplicación del administrador de tareas.

La pregunta es: ¿cómo puedo aprovechar el momento antes de que se mate la aplicación?

Este es el código Traté de usar:

@Override 
public void onDestroy() { 
    sendMessage(msg); 
    Log.d("SampleApp", "destroy"); 
    super.onDestroy(); 
} 

@Override 
public void finish(){ 

    sendMessage(msg); 
    Log.d("SampleApp", "finish"); 
    super.finish(); 
} 

Desafortunadamente acabado() no se llama y OnDestroy no se llama cada vez que cierro la aplicación desde el administrador de tareas.

¿Cómo puedo manejar esto?

+0

¿Se refiere a cuando el sistema anula la aplicación, cuando el usuario presiona Forzar detención en la configuración o simplemente cuando se presiona el botón INICIO o ATRÁS mientras mira su actividad? – Devunwired

+0

Ambos están bien para mí, me gustaría aprovechar el momento en que el usuario mata la aplicación del administrador de tareas (o presiona largamente la pantalla de inicio y elimina la aplicación desde allí, en un sándwich de helado) pero está bien también capturando el momento en que el usuario presiona el botón INICIO o ATRÁS para ver mi actividad. –

Respuesta

13

Como se indica en la documentación here, no hay garantía de que onDestroy() se llame. En su lugar, use onPause() para hacer las cosas que desea hacer cada vez que la aplicación se mueve a un segundo plano, y deje solo el código en onDestroy() que desea ejecutar cuando se mata su aplicación.

EDIT:

Desde sus comentarios, parece que desea ejecutar un código cada vez que su aplicación va a un segundo plano, pero no si se entró en el fondo, porque se puso en marcha un intento. Que yo sepa, no existe un método en Android que se encarga de esto por defecto, pero se puede usar algo como esto:

Tener un booleano como:

boolean usedIntent = false; 

Ahora antes de usar una intención, establezca el valor booleano true. En su onPause(), mueva el código para el caso de la intención en un bloque if como éste:

if(usedIntent) 
{ 
//Your code 
} 

Por último, en su onResume(), establece el booleano false nuevo para que pueda hacer frente a su la aplicación que se mueve a un segundo plano por un no intencionado significa correctamente.

+0

Ya lo leí pero el problema es que si pongo mi código en onPause() también se ejecutará si comienzo una nueva intención en mi aplicación. En cambio, me gustaría enviar mi mensaje solo cuando se llama a OnPause para volver a la pantalla de inicio –

+0

Solo la pantalla de inicio, u otra aplicación como cuando entra una llamada, o el usuario ve una notificación? –

+0

digamos que me gustaría saber cuando mi aplicación ya no se muestre (por lo que se queda en segundo plano por cualquier motivo), pero no quiero hacer nada cuando se inicia un intento porque comencé una nueva intención desde mi aplicación –

13

Su aplicación no recibirá ninguna devolución de llamada adicional si el proceso finaliza por medios externos (es decir, cancelado por razones de memoria o el usuario Fuerza detiene la aplicación). Tendrá que conformarse con las devoluciones de llamada que recibió cuando su aplicación pasó a segundo plano para la limpieza de su aplicación.

finish() solo es llamado por el sistema cuando el usuario presiona el botón ATRÁS de su Actividad, aunque a menudo las aplicaciones lo llaman directamente para dejar una Actividad y regresar a la anterior. Esta no es técnicamente una devolución de llamada del ciclo de vida.

onDestroy() solo se invoca en una actividad como resultado de una llamada al finish(), por lo que principalmente solo cuando el usuario presiona el botón ATRÁS. Cuando el usuario pulsa el botón INICIO, la Actividad en primer plano solo pasa por onPause() y onStop().

Esto significa que Android no proporciona demasiada información a una Actividad para diferenciar a un usuario que se dirige a Casa en lugar de moverse a otra Actividad (desde su aplicación o cualquier otra); la actividad en sí misma simplemente sabe que ya no está en primer plano.Una aplicación de Android es más una colección suelta de Actividades que un concepto singular estrechamente integrado (como puede estar acostumbrado en otras plataformas), por lo que no hay devoluciones de llamada del sistema reales para saber cuándo se ha presentado su solicitud como un todo o movido hacia atrás.

En última instancia, le instaría a reconsiderar la arquitectura de su aplicación si se basa en el conocimiento de si CUALQUIER actividad en su aplicación está en primer plano, pero dependiendo de sus necesidades, puede haber otras formas más amigables con el marco lograr esto Una opción es implementar un límite Service dentro de su aplicación que cada Activity se enlaza mientras está activo (es decir, entre onStart() y onStop()). Lo que esto le proporciona es la capacidad de aprovechar el hecho de que un Service enlazado solo vive mientras los clientes estén vinculados a él, por lo que puede supervisar los métodos onCreate() y onDestroy()del Servicio para saber cuándo la tarea de primer plano actual no es parte de tu aplicación.

También puede encontrar this article escrito por Dianne Hackborn para ser interesante que cubre con más detalle la arquitectura de Android y cómo Google piensa que debe ser utilizado.

+0

Creo que esta es una manera más adecuada, creo que también debería agregar una interfaz (o clase abstracta) en la aplicación para imponer actividades (o componentes) recién agregados para definir el comportamiento para esto. –

+0

https://developer.android.com/guide/components/activities/activity-lifecycle.html –

0

Acabo de resolver un tipo similar de problema.

Esto es lo que puede hacer si se cancela el servicio cuando el servicio se interrumpe al deslizar desde la lista de aplicaciones recientes.

Dentro de su archivo Manifiesto, mantenga la bandera stopWithTask como true para el Servicio. Al igual que:

<service 
    android:name="com.myapp.MyService" 
    android:stopWithTask="true" /> 

Pero como usted dice que desea anular el registro de los oyentes y dejar de notificación, etc, sugeriría este enfoque:

  1. Dentro de su archivo de manifiesto, mantener la bandera stopWithTask como false de servicio. Al igual que:

    <service 
        android:name="com.myapp.MyService" 
        android:stopWithTask="false" /> 
    
  2. Ahora en su servicio MyService, método de reemplazo onTaskRemoved. (Esto se disparará solo si stopWithTask está establecido en false).

    public void onTaskRemoved(Intent rootIntent) { 
    
        //unregister listeners 
        //do any other cleanup if required 
    
        //stop service 
        stopSelf(); 
    } 
    

Consulte my question para más detalles, que contiene otra parte del código, también.

    servicio
  1. de inicio, como a continuación

StartService (nueva Intención (esto, MyService.class));

Espero que esto ayude.

Cuestiones relacionadas