Ligera variación en mi otra publicación
Básicamente, tengo un mensaje Handler
en mi Fragment
que recibe un montón de mensajes que pueden hacer que los diálogos se descarten o se muestren.
Cuando la aplicación se coloca en segundo plano, obtengo un onPause
mensaje, pero aún así recibo mis mensajes como era de esperar. Sin embargo, debido a que estoy usando fragmentos, no puedo simplemente descartar y mostrar diálogos, ya que eso dará como resultado un archivo IllegalStateException
.
No puedo simplemente descartar o cancelar permitiendo la pérdida del estado.
Dado que tengo un Handler
, me pregunto si existe un enfoque recomendado sobre cómo debo manejar los mensajes mientras estoy en pausa.
Una posible solución que estoy considerando es grabar los mensajes que llegan mientras están en pausa y reproducirlos en formato onResume
. Esto es algo insatisfactorio y estoy pensando que debe haber algo en el marco para manejar esto de manera más elegante.
Respuestas:
Aunque el sistema operativo Android no parece tener un mecanismo que aborde suficientemente su problema, creo que este patrón proporciona una solución relativamente simple de implementar.
La siguiente clase es un contenedor
android.os.Handler
que almacena los mensajes cuando una actividad está en pausa y los reproduce en el currículum.Asegúrese de que cualquier código que tenga que cambie de forma asincrónica el estado de un fragmento (por ejemplo, confirmar, descartar) solo se llame desde un mensaje en el controlador.
Derive a su controlador de la
PauseHandler
clase.Siempre que su actividad reciba una
onPause()
llamadaPauseHandler.pause()
y paraonResume()
llamarPauseHandler.resume()
.Reemplace su implementación del Handler
handleMessage()
conprocessMessage()
.Proporcionar una implementación sencilla de la
storeMessage()
que siempre regresetrue
.A continuación se muestra un ejemplo simple de cómo
PausedHandler
se puede usar la clase.Al hacer clic en un botón, se envía un mensaje retrasado al administrador.
Cuando el controlador recibe el mensaje (en el hilo de la interfaz de usuario), muestra un
DialogFragment
.Si la
PausedHandler
clase no se estaba utilizando, se mostraría una IllegalStateException si se presionaba el botón de inicio después de presionar el botón de prueba para iniciar el cuadro de diálogo.Agregué un
storeMessage()
método a laPausedHandler
clase en caso de que algún mensaje deba procesarse inmediatamente incluso cuando la actividad está en pausa. Si se maneja un mensaje, se debe devolver falso y el mensaje se descartará.fuente
resume
método utilizasendMessage(msg)
técnicamente, podría haber otros subprocesos que pongan en cola el mensaje justo antes (o entre iteraciones del bucle), lo que significa que los mensajes almacenados podrían intercalarse con la llegada de nuevos mensajes. No estoy seguro de si es un gran problema. ¿Quizás usarsendMessageAtFrontOfQueue
(y por supuesto iterar hacia atrás) resolvería este problema?Una versión ligeramente más simple del excelente PauseHandler de quickdraw es
Se asume que siempre desea almacenar mensajes sin conexión para reproducirlos. Y proporciona la Actividad como entrada para
#processMessages
que no necesite administrarla en la subclase.fuente
resume()
ypause()
, yhandleMessage
synchronized
?Aquí hay una forma ligeramente diferente de abordar el problema de realizar confirmaciones de Fragmento en una función de devolución de llamada y evitar el problema IllegalStateException.
Primero cree una interfaz ejecutable personalizada.
A continuación, cree un fragmento para procesar los objetos MyRunnable. Si el objeto MyRunnable se creó después de que se pausó la actividad, por ejemplo, si se gira la pantalla o el usuario presiona el botón de inicio, se coloca en una cola para procesarlo posteriormente con un nuevo contexto. La cola sobrevive a cualquier cambio de configuración porque la instancia de setRetain se establece en true. El método runProtected se ejecuta en el subproceso de la interfaz de usuario para evitar una condición de carrera con el indicador isPaused.
Finalmente, el fragmento se puede usar en una aplicación principal de la siguiente manera:
fuente
En mis proyectos, uso el patrón de diseño del observador para resolver esto. En Android, los receptores de difusión y las intenciones son una implementación de este patrón.
Lo que hago es crear un BroadcastReceiver la que me registro en un fragmento de la / actividad onResume y anular el registro en el fragmento de de / actividad onPause . En BroadcastReceiver método 's OnReceive pongo todo el código que necesitan ser ejecutadas como resultado de - el BroadcastReceiver - recibir una Intención (mensaje) que es enviada a su aplicación en general. Para aumentar la selectividad sobre qué tipo de intenciones puede recibir su fragmento, puede usar un filtro de intenciones como en el ejemplo siguiente.
Una ventaja de este enfoque es que el Intent (mensaje) se puede enviar desde cualquier lugar dentro de su aplicación (un diálogo que se abrió encima de su fragmento, una tarea asíncrona, otro fragmento, etc.). Los parámetros pueden incluso pasar como extras de intención.
Otra ventaja es que este enfoque es compatible con cualquier versión de API de Android, ya que BroadcastReceivers e Intents se han introducido en el nivel de API 1.
No es necesario que configure ningún permiso especial en el archivo de manifiesto de su aplicación, excepto si planea usar sendStickyBroadcast (donde necesita agregar BROADCAST_STICKY).
fuente