Borra toda la pila de historiales e inicia una nueva actividad en Android
¿Es posible iniciar una actividad en la pila, borrando toda la historia antes?
La situación
- Gestión de títulos de barras de acción al usar fragmentos y el backstack
- ¿Cómo eliminar la actividad singleTask con taskAffinity de las tareas recientes cuando está terminado?
- Android: abrir la actividad sin guardar en la pila
- La forma correcta de manejar la navegación "Up" de acuerdo con las directrices
- Fragmento onResume () no se llama cuando se salió de backstack
Tengo una pila de actividades que va A-> B-> C o B-> C (la pantalla A selecciona el token de los usuarios, pero muchos usuarios solo tienen un solo token).
En la pantalla C el usuario puede tomar una acción que hace que la pantalla B sea inválida, por lo que la aplicación quiere llevarlos a la pantalla A, independientemente de si ya está en la pila. La pantalla A debe ser el único elemento de la pila en mi aplicación.
Notas
Hay muchas otras preguntas similares, pero no he encontrado nada que responda a esta pregunta exacta. Intenté llamar a getParent().finish()
– esto siempre resulta en una excepción de puntero nulo. FLAG_ACTIVITY_CLEAR_TOP
sólo funciona si la actividad ya está en la pila.
- Android - Utilizar el dedo de izquierda a derecha para volver
- Android deep linking - Pila trasera
- El fragmento que se obtiene de backstack, llama onCreateView () de nuevo
- Se reanuda el fragmento que no es el más alto en backstack
- Detener fragmento de ser recreado después de reanudar?
- Cómo borrar backStack de soporte FragmentManager?
- Fragmento onResume () & onPause () no se llama en backstack
- Android Fragmento Back Stack
En el nivel 11 de la API, se agregó una nueva bandera de intención sólo para esto: Intent.FLAG_ACTIVITY_CLEAR_TASK
Sólo para aclarar, utilice esto:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
Desafortunadamente para API lvl <= 10, todavía no he encontrado una solución limpia para esto. La solución "DontHackAndroidLikeThis" es puramente hackery puro. No deberías hacer eso. 🙂
Editar: Según el comentario @ Ben Pearson , para API <= 10 ahora se puede utilizar la clase IntentCompat para el mismo. Se puede usar el indicador de IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
para borrar la tarea. Por lo tanto, puede admitir pre API nivel 11 también.
Caso 1: Sólo dos actividades A y B:
Aquí el flujo de actividad es A-> B. Al hacer clic en el botón backbutton de B debemos cerrar la aplicación y luego iniciar la Actividad B desde A sólo llamar finish () esto evitará que android almacene la Actividad A en Backstack.eg para la actividad A es Pantalla Loding / Splash de la aplicación.
Intent newIntent = new Intent(A.this, B.class); startActivity(newIntent); finish();
Caso 2: Más de dos actividades:
Si hay un flujo como A-> B-> C-> D-> B y al pulsar el botón Atrás en la Actividad B mientras viene de la Actividad D.En ese caso deberíamos usar.
Intent newIntent = new Intent(D.this,B.class); newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(newIntent);
Aquí la Actividad B se iniciará desde la backstack en lugar de una nueva instancia debido a Intent.FLAG_ACTIVITY_CLEAR_TOP y Intent.FLAG_ACTIVITY_NEW_TASK borra la pila y la convierte en la primera. Así que cuando presionamos el botón de volver a la aplicación completa se terminará.
Pasé unas horas en esto también … y estoy de acuerdo en que FLAG_ACTIVITY_CLEAR_TOP suena como lo que querrías: despejar la pila entera, excepto la actividad que se está iniciando, por lo que el botón Atrás sale de la aplicación. Sin embargo, como Mike Repass mencionó, FLAG_ACTIVITY_CLEAR_TOP sólo funciona cuando la actividad que está lanzando ya está en la pila; Cuando la actividad no está allí, la bandera no hace nada.
¿Qué hacer? Ponga la actividad que se está iniciando en la pila con FLAG_ACTIVITY_NEW_TASK, lo que hace que la actividad sea el inicio de una nueva tarea en la pila de historial. A continuación, agregue el indicador FLAG_ACTIVITY_CLEAR_TOP.
Ahora, cuando FLAG_ACTIVITY_CLEAR_TOP va a encontrar la nueva actividad en la pila, estará ahí y se detendrá 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 está conectada la función.
public void onLogoutClick(final View view) { Intent i = new Intent(this, Splash.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(i); finish(); }
No debe cambiar la pila. El botón de retroceso de Android debería funcionar como en un navegador web.
Puedo pensar en una manera de hacerlo, pero es bastante un hack.
-
Haga que sus Actividades
singleTask
agregándolo alAndroidManifest
Ejemplo:<activity android:name=".activities.A" android:label="@string/A_title" android:launchMode="singleTask"/> <activity android:name=".activities.B" android:label="@string/B_title" android:launchMode="singleTask"/>
-
Amplíe la
Application
que mantendrá la lógica de dónde ir.
Ejemplo:
public class DontHackAndroidLikeThis extends Application { private Stack<Activity> classes = new Stack<Activity>(); public Activity getBackActivity() { return classes.pop(); } public void addBackActivity(Activity activity) { classes.push(activity); } }
De A a B:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication(); app.addBackActivity(A.class); startActivity(this, B.class);
De B a C:
DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication(); app.addBackActivity(B.class); startActivity(this, C.class);
Cª:
If ( shouldNotGoBackToB() ) { DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication(); app.pop(); }
Y manejar el botón de retroceso a pop()
de la pila.
Una vez más, no deberías hacer esto 🙂
Con la versión más reciente de Android> = API 16 use finishAffinity()
Es adecuado para> = API 16.
Intent mIntent = new Intent(mContext,MainActivity.class); finishAffinity(); startActivity(mIntent);
- Es igual que iniciar nueva Actividad, y borrar toda la pila.
- O Reinicie a MainActivity / FirstActivity.
Inmediatamente después de iniciar una nueva actividad, utilizando startActivity
, asegúrese de llamar a finish()
para que la actividad actual no se apile detrás de la nueva.
He encontrado hack demasiado simple hacer esto añadir nuevo elemento en AndroidManifest
como: –
<activity android:name=".activityName" android:label="@string/app_name" android:noHistory="true"/>
El android:noHistory
borrará su actividad no deseada de Stack.
Prueba esto:
Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class); logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); startActivity(logout_intent); finish();
A veces, el emulador de Android podría fallar al conectar la herramienta eclipse DDMS y pedir que se inicie manualmente. En ese caso, puede iniciar o detener el adb mediante el símbolo del sistema.