2010-10-10 5 views
27

Necesito mi aplicación de Android para guardar su estado en el disco cuando su actividad se pone en segundo plano o muere. Se ha sugerido que inicie un hilo cuando se llame a OnPause() y realice algún procedimiento costoso de E/S allí (vea Saving/loading document state quickly and robustly for image editor).¿Cómo maneja Android los hilos de fondo cuando sale de una actividad?

¿En qué situaciones el sistema operativo matará al hilo y con qué frecuencia ocurren estas situaciones?

Supongo que será como la forma en que se manejan las actividades donde el sistema operativo puede arbitrariamente decidir eliminar el hilo, pero principalmente solo lo hará cuando los recursos sean extremadamente limitados. Sin embargo, sería bueno encontrar documentación específica de esto.

Al jugar, con algunos códigos de prueba, un hilo de fondo iniciado en onPause() se ejecutará indefinidamente en segundo plano en mi dispositivo (traté de cargar muchas aplicaciones y no pude lograr que se matara).

Para mi aplicación específica, estoy escribiendo un editor de mapas de bits en el que estoy usando el patrón Command y el patrón Memento para permitir deshacer y rehacer las ediciones. Me gustaría que el usuario pueda deshacer/rehacer sus ediciones, por ejemplo, el usuario recibe una llamada telefónica y la actividad se cancela cuando se pone en segundo plano. La mejor solución que se me ocurre es usar un hilo de fondo para guardar constantemente mis comandos y recuerdos en el disco durante el uso de la aplicación y para terminar de guardar los objetos que quedan en una hebra de fondo si se invoca a OnPause. En el peor de los casos, si el hilo se mata, solo perderé algunas ediciones.

Respuesta

21

¿En qué situaciones el sistema operativo matará al hilo y con qué frecuencia ocurren estas situaciones?

El sistema operativo no va a matar el hilo, a menos que esté matando el proceso: Android no hace nada con los hilos que crea usted mismo. Si eres el proceso en primer plano, no te matarán. Las probabilidades de que Android mate el proceso en unos pocos segundos después de perder el primer plano (después de onPause()) son minúsculas. La documentación sobre la vida útil del proceso, lo que hay, se puede encontrar en here.

+1

Solo para aclarar, si crea un hilo en el proceso que se adjunta a alguna actividad, este hilo se eliminará cuando se mate la actividad (es decir, el proceso y el hilo están vinculados)? – memcom

+2

@tifftuff: una actividad no es una aplicación. Una actividad es un componente de una aplicación. Una aplicación puede tener muchos componentes, incluidas actividades múltiples, servicios, etc. Cuando se destruye el último componente de una aplicación (por ejemplo, el usuario presiona ATRÁS desde la actividad única en una aplicación pequeña), el proceso se destina al reciclaje. o terminación. NO FUGAS HILOS. Si inicia el hilo, debe hacer los arreglos para que finalice, ya que Android no lo rescindirá por usted, a menos que finalice el proceso, lo que puede no ocurrir en algunas semanas. – CommonsWare

+0

Gracias. ¿Tiene alguna recomendación sobre si un Servicio sería más apropiado para usar que un hilo para este trabajo en segundo plano? – memcom

1

Normalmente, guardar su estado en es lo correcto a hacer si es rápido. No creo que esté claramente documentado cuando se mata un proceso, pero a veces lo ves en Logcat cuando ejecutas algunas aplicaciones exigentes (por ejemplo, después de ejecutar Google Earth y el navegador).

También hay una opción en las DevTools de Android para destruir automáticamente las actividades a medida que se aleja de ellas, aunque eso probablemente no se extienda al proceso. (DevTools está en el emulador y en algunos teléfonos rooteados).

Creo que su enfoque suena razonable: use un subproceso de baja prioridad para actualizar constantemente los datos de guardado, asígnele prioridad normal en OnPause y configure un indicador en onPause que le indique que termine una vez que finalice.

Obviamente, deberá asegurarse de no encontrarse con problemas de sincronización si ejecuta OnResume inmediatamente después de onPause (es decir, mientras el hilo aún está ocupado guardando).

5

Su cadena se puede matar en cualquier momento después de que se destruya la actividad, o nunca se puede matar. Dependiendo de ese hilo, la forma es muy mala: podrías terminar con una operación a medio completar o con un hilo que se queda para siempre.

Si desea realizar una operación de fondo que continúe incluso cuando no hay actividad de primer plano, casi siempre desea ejecutarla dentro de un servicio.Por otro lado, el servicio es menos probable por matar, pero no hay garantía a menos que use "startForeground". Esto terminará mostrando una notificación al usuario de que algo está sucediendo en segundo plano, pero hasta donde yo sé, es la única forma de ejecutar un hilo de fondo asíncrono que garantiza que no se matará.

Honestamente, la respuesta correcta es asegurarse de que nunca haya ningún estado de proceso temporal que tarde mucho en guardarse. Si tiene que escribir un archivo grande para reflejar algunos cambios de usuario, considere mantener un "registro de transacciones" que puede usar para crear una operación de restauración reiniciable. Dado esto, puede ejecutar de manera segura sus grabaciones en un servicio y saber que incluso si muere, se reiniciará automáticamente cuando los recursos estén disponibles.

+0

El hilo terminará dentro de unos 5 segundos mientras espero para confirmar que mis datos se escribieron en el disco (aproximadamente 2 Mb de valor). Mi cargador de autoguardado tendrá en cuenta que el hilo podría ser eliminado antes de terminar y el usuario podría perder 30 segundos de trabajo. ¿No crees que comenzar un servicio para esto es un poco pesado? Podría crear un registro de transacciones de las operaciones de edición, pero también deben guardarse en el disco al salir (¿dónde más puedo guardarlo rápidamente?) Y el usuario podría hacer una gran edición y luego ser interrumpido. – memcom

+1

Iniciar un nuevo servicio es absolutamente * no * demasiado pesado. Esta es la manera recomendada de hacer las cosas cuando, por ejemplo, procesar una notificación de widget si va a tomar más de un segundo más o menos. Los servicios proporcionan * exactamente * lo que está buscando: el sistema se dará cuenta de que tiene una buena razón para quedarse y tratará de evitar matarlos de forma preventiva, para que pueda estar más seguro de que obtendrá su 5 segundos de procesamiento en segundo plano. Parece que ya estás preparado para el raro caso en que el servicio necesita ser asesinado, así que eso es todo lo que necesitas. – beekeeper

Cuestiones relacionadas