Todas las actividades en mi aplicación requieren que un usuario inicie sesión para ver. Los usuarios pueden cerrar sesión en casi cualquier actividad. Este es un requisito de la aplicación. En cualquier momento, si el usuario cierra sesión, quiero enviarlo al inicio de sesión Activity
. En este punto, quiero que esta actividad se encuentre en la parte inferior de la pila de historial para que al presionar el botón "atrás" el usuario vuelva a la pantalla de inicio de Android.
He visto esta pregunta en diferentes lugares, todos respondidos con respuestas similares (que describo aquí), pero quiero plantearla aquí para recopilar comentarios.
Intenté abrir la actividad de inicio de sesión configurando sus Intent
indicadores, FLAG_ACTIVITY_CLEAR_TOP
que parecen hacer lo que se describe en la documentación, pero no alcanzo mi objetivo de colocar la actividad de inicio de sesión en la parte inferior de la pila del historial y evitar que el usuario navegue hacia atrás a actividades registradas previamente vistas. También intenté usar android:launchMode="singleTop"
para la actividad de inicio de sesión en el manifiesto, pero esto tampoco cumple mi objetivo (y parece no tener ningún efecto de todos modos).
Creo que necesito borrar la pila de historial o terminar todas las actividades abiertas anteriormente.
Una opción es hacer que cada actividad onCreate
verifique el estado de inicio de sesión, y finish()
si no está conectado. No me gusta esta opción, ya que el botón Atrás todavía estará disponible para su uso, navegando hacia atrás a medida que las actividades se cierran.
La siguiente opción es mantener una LinkedList
referencia de todas las actividades abiertas a las que está accesible estáticamente desde cualquier lugar (quizás utilizando referencias débiles). Al cerrar sesión, accederé a esta lista e iteraré sobre todas las actividades abiertas anteriormente, invocando finish()
cada una. Probablemente comenzaré a implementar este método pronto.
Intent
Sin embargo, prefiero usar algunos trucos de bandera para lograr esto. Me encantaría descubrir que puedo cumplir con los requisitos de mi aplicación sin tener que usar ninguno de los dos métodos que describí anteriormente.
¿Hay alguna manera de lograr esto mediante el uso Intent
o la configuración de manifiesto, o es mi segunda opción, mantener una LinkedList
de las actividades abiertas la mejor opción? ¿O hay otra opción que estoy pasando por alto por completo?
Parece un rito de pasaje que un nuevo programador de Android pasa un día investigando este problema y leyendo todos estos hilos de StackOverflow. Ahora estoy recién iniciado y dejo aquí un rastro de mi humilde experiencia para ayudar a un futuro peregrino.
Primero, no hay una manera obvia o inmediata de hacer esto según mi investigación
(as of September 2012).
. Pensarías que podrías ser simplestartActivity(new Intent(this, LoginActivity.class), CLEAR_STACK)
pero no .PUEDE hacerlo
startActivity(new Intent(this, LoginActivity.class))
conFLAG_ACTIVITY_CLEAR_TOP
- y esto hará que el marco busque en la pila, encuentre su instancia original anterior de LoginActivity, vuelva a crearla y elimine el resto de la pila (hacia arriba). Y dado que el inicio de sesión está presumiblemente en la parte inferior de la pila, ahora tiene una pila vacía y el botón Atrás acaba de salir de la aplicación.PERO: esto solo funciona si previamente dejó viva esa instancia original de LoginActivity en la base de su pila. Si, como muchos programadores, eliges
finish()
esoLoginActivity
una vez que el usuario ha iniciado sesión con éxito, entonces ya no está en la base de la pila y laFLAG_ACTIVITY_CLEAR_TOP
semántica no se aplica ... terminas creando una nuevaLoginActivity
encima de la pila existente. Lo cual es casi seguro que NO es lo que desea (comportamiento extraño en el que el usuario puede 'retroceder' para iniciar sesión en una pantalla anterior).Así que si usted previamente
finish()
'd laLoginActivity
, que necesita para continuar algún mecanismo para la limpieza de su pila y luego iniciar una nuevaLoginActivity
. Parece que la respuesta@doreamon
en este hilo es la mejor solución (al menos para mi humilde ojo):https://stackoverflow.com/a/9580057/614880
Sospecho firmemente que las complicadas implicaciones de si dejas LoginActivity vivo están causando mucha confusión.
Buena suerte.
fuente
ACTUALIZAR
El súper
finishAffinity()
método ayudará a reducir el código pero logrará lo mismo. Terminará la actividad actual, así como todas las actividades en la pila, úselagetActivity().finishAffinity()
si está en un fragmento.RESPUESTA ORIGINAL
Suponga que LoginActivity -> HomeActivity -> ... -> SettingsActivity call signOut ():
InicioActividad:
Esto funciona para mí, espero que también sea útil para usted. :)
fuente
Si está utilizando API 11 o superior, puede intentar esto:
FLAG_ACTIVITY_CLEAR_TASK
parece estar abordando exactamente el problema que está teniendo. Obviamente, la multitud anterior a API 11 tendría que usar alguna combinación de hacer que todas las actividades verifiquen un extra, como sugiere @doreamon, o algún otro truco.(También tenga en cuenta: para usar esto debe pasar
FLAG_ACTIVITY_NEW_TASK
)fuente
finish();
haré el trabajo para evitar volver después de cerrar sesión. ¿Cuál es la necesidad de configurar banderas?También pasé unas horas en esto ... y estoy de acuerdo en que FLAG_ACTIVITY_CLEAR_TOP suena como lo que quieres: borra toda la pila, excepto la actividad que se inicia, por lo que el botón Atrás sale de la aplicación. Sin embargo, como mencionó Mike Repass , FLAG_ACTIVITY_CLEAR_TOP solo funciona cuando la actividad que está iniciando ya está en la pila; cuando la actividad no está allí, la bandera no hace nada.
¿Qué hacer? Coloque la actividad que se inicia en la pila con FLAG_ACTIVITY_NEW_TASK , lo que hace que esa actividad sea el inicio de una nueva tarea en la pila del historial. Luego agregue el indicador FLAG_ACTIVITY_CLEAR_TOP.
Ahora, cuando FLAG_ACTIVITY_CLEAR_TOP vaya a buscar la nueva actividad en la pila, estará allí y se levantará antes de que se borre todo lo demás.
Aquí está mi función de cierre de sesión; El parámetro Ver es el botón al que se adjunta la función.
fuente
FLAG_ACTIVITY_CLEAR_TASK
se ha añadido todavía noMuchas respuestas Puede ser este también ayudará
Versión Kotlin
fuente
Use esto, debería ser útil para usted. Respuesta ligeramente modificada de xbakesx.
fuente
La solución aceptada no es correcta, tiene problemas ya que el uso de un receptor de difusión no es una buena idea para este problema. Si su actividad ya ha llamado al método onDestroy (), no obtendrá el receptor. La mejor solución es tener un valor booleano en sus preferencias compartidas y verificarlo en el método onCreate () de su actividad. Si no se debe llamar cuando el usuario no ha iniciado sesión, finalice la actividad. Aquí hay un código de muestra para eso. Tan simple y funciona para todas las condiciones.
fuente
onResume()
método. Porque cuando presiona el botón Atrás, es más probable que la actividad se reanude en lugar de crearse.Algún tiempo
finish()
no funcionaHe resuelto ese problema con
finishAffinity()
fuente
Sugeriría un enfoque diferente a esta pregunta. Quizás no sea el más eficiente, pero creo que es el más fácil de aplicar y requiere muy poco código. Escribir el siguiente código en su primera actividad (actividad de inicio de sesión, en mi caso) no permitirá que el usuario regrese a las actividades iniciadas anteriormente después de cerrar sesión.
Supongo que LoginActivity finaliza justo después de que el usuario inicie sesión, para que no pueda volver más tarde presionando el botón Atrás. En cambio, el usuario debe presionar un botón de cerrar sesión dentro de la aplicación para cerrar sesión correctamente. Lo que implementaría este botón de cerrar sesión es una simple intención de la siguiente manera:
Todas las sugerencias son bienvenidas.
fuente
La respuesta seleccionada es inteligente y engañosa. Así es como lo hice:
LoginActivity es la actividad raíz de la tarea, configure android: noHistory = "true" en Manifest.xml; Supongamos que desea cerrar sesión desde SettingsActivity, puede hacerlo de la siguiente manera:
fuente
Aquí está la solución que se me ocurrió en mi aplicación.
En mi LoginActivity, después de procesar con éxito un inicio de sesión, comienzo el siguiente de manera diferente según el nivel de API.
Luego, en mi método onActivityForResult de LoginActivity:
Finalmente, después de procesar un cierre de sesión en cualquier otra Actividad:
Cuando estoy en Gingerbread, lo hace así si presiono el botón Atrás de MainActivity, LoginActivity se oculta inmediatamente. En Honeycomb y versiones posteriores, acabo de finalizar LoginActivity después de procesar un inicio de sesión y se vuelve a crear correctamente después de procesar un cierre de sesión.
fuente
Esto funcionó para mí:
fuente
Comience su actividad con StartActivityForResult y mientras cierra la sesión, configure su resultado y, según su resultado, finalice su actividad
fuente
La solución proporcionada por @doreamon funciona bien para todos los casos, excepto uno:
Si después de iniciar sesión, el usuario de la pantalla de inicio de sesión de Killing navegó directamente a una pantalla central. Por ejemplo, en un flujo de A-> B-> C, navegue como: Iniciar sesión -> B -> C -> Presione acceso directo a inicio. El uso de FLAG_ACTIVITY_CLEAR_TOP borra solo la actividad C, ya que la página de inicio (A) no está en el historial de la pila. Presionando Atrás en la pantalla A nos llevará de regreso a B.
Para abordar este problema, podemos mantener una pila de actividades (Arraylist) y cuando se presiona el inicio, tenemos que eliminar todas las actividades en esta pila.
fuente
Es posible administrando un indicador en SharedPreferences o en Application Activity.
Al iniciar la aplicación (en la pantalla de bienvenida) establezca la bandera = falso; Al cerrar sesión, haga clic en el evento solo establezca el indicador verdadero y en OnResume () de cada actividad, verifique si el indicador es verdadero y luego llame a terminar ().
Funciona a las mil maravillas :)
fuente
al hacer clic en Cerrar sesión, puede llamar a esto
onActivityResult () de la actividad anterior, vuelva a llamar a este código anterior hasta que finalice todas las actividades.
fuente
Lo que desea hacer es llamar a logout () y finish () en sus métodos onStop () o onPause (). Esto obligará a Android a llamar a onCreate () cuando la actividad se vuelva a activar ya que ya no la tendrá en la pila de su actividad. Luego haga lo que dice, en onCreate () verifique el estado de inicio de sesión y reenvíe a la pantalla de inicio de sesión si no está conectado.
Otra cosa que puede hacer es verificar el estado de inicio de sesión en onResume () y, si no está conectado, finalizar () e iniciar la actividad de inicio de sesión.
fuente