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

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.

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 al AndroidManifest 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.

  • PopBackStack pero mantener el primer fragmento en android
  • Uso del botón backstack y back en viewpager
  • Después de que el fragmento de cambio de configuración de backstack ahora está compartiendo el FrameLayout?
  • Quitar fragmento medio de FragmentStack
  • Intent.FLAG_ACTIVITY_CLEAR_TOP no funciona
  • Mal comportamiento de Backstack de la actividad cuando la actividad destruida
  • Cómo persistir los datos de fragmentos después de las transacciones backstack?
  • Botón Atrás cerrar la aplicación incluso cuando se utiliza FragmentTransaction.addToBackStack ()
  • ¿Cómo excluir de una actividad exportada?
  • PopBackStack hace que llamar a oncreateView del fragmento una y otra vez
  • Android - guardar / restaurar estado de fragmento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.