Tengo una pantalla de presentación en un temporizador. Mi problema es que antes de comenzar finish()
mi actividad necesito verificar que la siguiente actividad haya comenzado porque aparece un cuadro de diálogo del sistema y solo quiero hacerlo finish()
; una vez que el usuario ha seleccionado una opción del cuadro de diálogo?
Sé que hay muchas preguntas sobre cómo ver si su actividad está en primer plano, pero no sé si esto también permite cuadros de diálogo en la parte superior de la actividad.
Aquí está el problema, el rojo es mi actividad que está en segundo plano mientras que el diálogo está en primer plano:
EDITAR: He intentado simplemente no usar, finish()
pero luego mi actividad puede volver a la pila de aplicaciones que estoy tratando de evitar.
Respuestas:
Esto es lo que se recomienda como solución adecuada :
En su
finish()
método, desea utilizarisActivityVisible()
para verificar si la actividad es visible o no. Allí también puedes comprobar si el usuario ha seleccionado una opción o no. Continúe cuando se cumplan ambas condiciones.La fuente también menciona dos soluciones incorrectas ... así que evite hacer eso.
Fuente: stackoverflow
fuente
onPause
,onStop
ni elonResume
evento se llama. Entonces, ¿qué haces si ninguno de estos eventos se dispara?Si tiene como objetivo el nivel de API 14 o superior, se puede usar android.app.Application.ActivityLifecycleCallbacks
fuente
UPD : actualizado al estado
Lifecycle.State.RESUMED
. Gracias a @htafoya por eso.En 2019, con la ayuda de la nueva biblioteca de soporte
28+
o AndroidX, simplemente puede usar:Puedes leer más en la documentación para comprender lo que sucedió bajo el capó.
fuente
activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)
o EMPEZAR.INITIALIZED
no garantiza que esté en primer plano.Activity :: hasWindowFocus () te devuelve el booleano que necesitas.
Aquí hay una clase de ejemplo para verificar la visibilidad de sus actividades desde donde se encuentre.
Recuerde que si muestra un diálogo , el resultado será falso ya que el diálogo tendrá el foco principal. Aparte de eso, es realmente útil y más confiable que las soluciones sugeridas.
fuente
Esa es exactamente la diferencia entre
onPause
yonStop
eventos de la actividad como se describe en la documentación de la clase Actividad .Si te entiendo bien, lo que quieres hacer es llamar
finish()
desde tu actividadonStop
para dar por terminada. Vea la imagen adjunta de la aplicación Activity Lifecycle Demo . Así es como se ve cuando la Actividad B se inicia desde la Actividad A. El orden de los eventos es de abajo hacia arriba para que pueda ver que la Actividad AonStop
se llama después de que la Actividad BonResume
ya se llamó.En caso de que se muestre un cuadro de diálogo, su actividad se atenuará en segundo plano y solo
onPause
se llamará.fuente
Dos posibles soluciones:
1) Devolución de llamada del ciclo de vida de la actividad
Utilice una aplicación que implemente ActivityLifecycleCallbacks y úsela para realizar un seguimiento de los eventos del ciclo de vida de las actividades en su aplicación. Tenga en cuenta que ActivityLifecycleCallbacks son para la api de Android> = 14. Para la api de Android anterior, deberá implementarla usted mismo dentro de todas sus actividades ;-)
Utilice la aplicación cuando necesite compartir / almacenar estados en todas las actividades.
2) Verifique la información del proceso en ejecución
Puede verificar el estado de un proceso en ejecución con esta clase RunningAppProcessInfo
Obtenga la lista de procesos en ejecución con ActivityManager.getRunningAppProcesses () y filtre la lista de resultados para verificar el RunningAppProcessInfo deseado y verificar su "importancia"
fuente
He creado un proyecto en github app-foreground-background-listen
que utiliza una lógica muy simple y funciona bien con todos los niveles de API de Android.
fuente
Utilice el intervalo de tiempo entre la pausa y la reanudación desde el fondo para determinar si está despierto desde el fondo
En aplicación personalizada
En la clase BaseActivity
fuente
Creo que tengo una mejor solución. Porque puede compilar simplemente en MyApplication.activityResumed (); a cada actividad en una extensión.
Primero tienes que crear (como CyberneticTwerkGuruOrc)
A continuación, debe agregar la clase de aplicación a AndroidManifest.xml
Luego, crea la clase ActivityBase
Finalmente, cuando crea una nueva Actividad, simplemente puede extenderla por ActivityBase en lugar de Activity.
Para mí, es un mejor método porque solo debes recordar sobre extender por ActivityBase. Además, puede ampliar su función básica en el futuro. En mi caso, agregué receptores para mi servicio y alertas sobre la red en una clase.
Si desea verificar la visibilidad de su aplicación, simplemente puede llamar
fuente
Esto puede lograr esto de una manera eficiente utilizando Application.ActivityLifecycleCallbacks
Por ejemplo, tomemos el nombre de la clase de actividad como ProfileActivity permite encontrar si está en primer plano o en segundo plano
primero tenemos que crear nuestra clase de aplicación ampliando la clase de aplicación
que implementa
Seamos mi clase de aplicación de la siguiente manera
Clase de aplicación
en la clase anterior hay un método de anulación enActivityResumed de ActivityLifecycleCallbacks
donde se pueden encontrar todas las instancias de actividad que se muestran actualmente en la pantalla, simplemente verifique si su actividad está en la pantalla o no mediante el método anterior.
Registre su clase de aplicación en manifest.xml
Para verificar el clima, la actividad está en primer plano o en segundo plano según la solución anterior, llame al siguiente método en los lugares que necesita verificar
fuente
Si desea saber si alguna actividad de su aplicación es visible en la pantalla, puede hacer algo como esto:
Simplemente cree un singleton de esta clase y configúrelo en su instancia de aplicación como se muestra a continuación:
¡Entonces puede usar el método isAnyActivityVisible () de su instancia MyAppActivityCallbacks en todas partes!
fuente
¿Intentaste no llamar a finish y poner "android: noHistory =" true "en el manifiesto? Esto evitará que la actividad vaya a la pila.
fuente
Debo decir que su flujo de trabajo no es estándar de Android. En Android, no necesita
finish()
su actividad si desea abrir otra actividad desde Intent. En cuanto a la conveniencia del usuario, Android le permite usar la tecla 'atrás' para volver de la actividad que abrió a su aplicación.Así que deje que el sistema detenga su actividad y guarde todo lo que sea necesario cuando se recupere su actividad.
fuente
Guarde una bandera si está pausado o reanudado. Si se reanuda, significa que está en primer plano.
fuente
Una posible solución podría ser establecer una bandera mientras se muestra el diálogo del sistema y luego en el método onStop del ciclo de vida de la actividad, verificar la bandera, si es verdadera, finalizar la actividad.
Por ejemplo, si el cuadro de diálogo del sistema se activa al hacer clic en un botón, entonces el oyente onclick podría ser como
y en la parada de la actividad:
fuente
¿Por qué no utilizar transmisiones para esto? la segunda actividad (la que necesita estar activada) puede enviar una transmisión local como esta:
luego escriba un receptor simple dentro de la actividad de bienvenida:
y registre su nuevo receptor con LocalBroadcastManager para escuchar la transmisión de su segunda actividad:
TENGA EN CUENTA que puede usar una constante o un recurso de cadena para la cadena "Identificador de difusión".
fuente
LocalBroadcastManager
aquíSi usa
finish()
solo para evitar que una nueva aplicación se inicie en la pila (tarea) de su aplicación, puede usar laIntent.FLAG_ACTIVITY_NEW_TASK
bandera al iniciar una nueva aplicación y no llamarfinish()
en absoluto. Según la documentación , esta es la bandera que se utilizará para implementar un comportamiento de estilo "lanzador".fuente
Utilice estos métodos dentro de un
Activity
.isDestroyed()
isFinishing()
Un error común con
AsyncTask
es capturar una fuerte referencia al hostActivity
(oFragment
):Esto es un problema porque
AsyncTask
puede sobrevivir fácilmente al padreActivity
, por ejemplo, si ocurre un cambio de configuración mientras se ejecuta la tarea.La forma correcta de hacer esto es hacer que su tarea sea una
static
clase, que no capture al padre y mantenga una referencia débil al hostActivity
:fuente
Aquí hay una solución usando
Application
class.Simplemente puede usarlo como sigue,
Si tiene una referencia a la Actividad requerida o usa el nombre canónico de la Actividad, puede averiguar si está en primer plano o no. Esta solución puede no ser infalible. Por lo tanto, sus comentarios son bienvenidos.
fuente
No sé por qué nadie habló sobre sharedPreferences, para la Actividad A, estableciendo una SharedPreference como esa (por ejemplo, en onPause ()):
Creo que esta es la forma confiable de rastrear la visibilidad de las actividades.
fuente
¿
Activity.onWindowFocusChanged(boolean hasFocus)
Sería útil aquí? Eso, más una bandera de nivel de clase, algo comoisFocused
esoonWindowFocusChanged
, sería una manera fácil de saber en cualquier punto de su actividad si está enfocado o no. Al leer los documentos, parece que se establecería correctamente como "falso" en cualquier situación en la que la actividad no esté directamente en el "primer plano" físico, como si se muestra un cuadro de diálogo o se abre la bandeja de notificaciones.Ejemplo:
fuente
Si está utilizando EventBus , es un método llamado
hasSubscriberForEvent
que puede usarse para verificar si unActivity
está enfocado.fuente
Solía hacer como
si la actividad no está en primer plano
devolverá nulo. : = P
fuente