2010-08-13 12 views
245

¿Es posible iniciar una actividad en la pila, borrando todo el historial anterior?Borrar toda la pila de historial y comenzar una nueva actividad en Android

La situación

I tienen una pila de actividad que o bien va A-> B-> C o B-> C (pantalla A selecciona de contadores a los usuarios, pero muchos usuarios sólo tienen un único token).

En la pantalla C el usuario puede realizar una acción que invalida la pantalla B, por lo que la aplicación desea llevarlos a la pantalla A, independientemente de si ya está en la pila. La pantalla A debería ser el único elemento en la pila en mi aplicación.

Notas

Hay muchas otras preguntas similares, pero no he encontrado nada que responde a esta pregunta exacta. Intenté llamar al getParent().finish(); esto siempre da como resultado una excepción de puntero nulo. FLAG_ACTIVITY_CLEAR_TOP solo funciona si la actividad ya está en la pila.

Respuesta

507

En el nivel API 11 una nueva bandera de Intención se añadió sólo para esto: Intent.FLAG_ACTIVITY_CLEAR_TASK

Solo para aclarar, utilice esto:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 

Desafortunadamente para API lvl < = 10, aún no he encontrado una solución limpia para esto. El "DontHackAndroidLikeThis" solution es de hecho puro hackeo. No deberías hacer eso.:)

Editar: Según Ben Pearson @ 's comentario, por < API = 10 ahora uno puede utilizar IntentCompat clase para el mismo. Uno puede usar el indicador IntentCompat.FLAG_ACTIVITY_CLEAR_TASK para borrar la tarea. Por lo tanto, también es compatible con el nivel pre API 11.

+21

Solo para aclarar, use esto: intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); – user123321

+2

sin Intent.FLAG_ACTIVITY_NEW_TASK la aplicación a veces solo se cierra en android 4 – max4ever

+20

IntentCompat también tiene un indicador para borrar la tarea ahora, por lo que puede admitir el nivel pre API 11 - http://developer.android.com/reference/android/ support/v4/content/IntentCompat.html # FLAG_ACTIVITY_CLEAR_TASK –

11

No debe cambiar la pila. El botón Atrás de Android debería funcionar como en un navegador web.

Puedo pensar en una forma de hacerlo, pero es bastante complicado.

  • Haga sus actividades singleTask añadiéndolo al Ejemplo AndroidManifest :

    <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"/> 
    
  • Extender Application que llevará a cabo la lógica de a 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 la 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); 

En C:

If (shouldNotGoBackToB()) { 
    DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication(); 
    app.pop(); 
} 

y maneje el botón de retroceso a pop() desde la pila.

Una vez más, usted no debe hacer esto :)

+0

Al final deciden abandonar la pila intacta y sólo decirle al usuario que su pantalla actual no es válido – Casebash

+1

muy frustrante que el androide no nos permite gestionar la pila de la actividad de esta manera ya. Estaría tentado de usar esta solución en mis futuras aplicaciones de Android. – Cephron

+4

Solo para que quede claro por qué no se debe utilizar: es una buena forma de crear pérdidas de memoria. En algún momento, el sistema operativo puede decidir eliminar las actividades en segundo plano, pero dado que 'Application' toma sus instancias, el sistema operativo no podrá liberar la RAM que queda de las actividades destruidas. –

8

Inmediatamente después de comenzar una nueva actividad, usando startActivity, asegúrese de llamar al finish() para que la actividad actual no se apile detrás de la nueva.

+0

+1 Buena solución para evitar que exactamente una actividad en una determinada situación se coloque en la pila del historial. – marsbear

+24

no funciona si tiene más de una actividad en la pila; el acabado borrará la actividad anterior pero no las demás ... – Necronet

32

Caso 1: Sólo dos actividades A y B:

Aquí flujo de actividad es A-> B .En clic BackButton de B tenemos que cerrar la aplicación a continuación, mientras que a partir de la actividad B Un acabado simplemente llamar() Esto evitará que Android almacene la Actividad A en Backstack.eg para la actividad A es la pantalla de aplicación Loding/Splash.

Intent newIntent = new Intent(A.this, B.class); 
startActivity(newIntent); 
finish(); 

Caso 2: Más de dos activitiy:

Si hay un flujo como A-> B-> C-> D> B y al hacer clic en el botón Atrás en la actividad B mientras que 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 el backstack en lugar de una nueva instancia debido Intent.FLAG_ACTIVITY_CLEAR_TOP y Intent.FLAG_ACTIVITY_NEW_TASK borra la pila y hace que la parte superior one.So cuando presionamos el botón toda la aplicación lo hará volver ser terminado.

+2

Esto funcionó para mí.Puse en TODAS las actividades esas banderas. En esas actividades, los botones de retroceso funcionan perfectamente yendo a la actividad anterior, y en la Actividad principal con Intent intennt = new Intent (Intent.ACTION_MAIN); intent.addCategory (Intent.CATEGORY_HOME); intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP); \t \t intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK); startActivity (intención); acabado(); Toda la aplicación está cerrada, todavía en la memoria pero no está activa, y si reinicia la aplicación va a la pantalla de bienvenida :) – Rako

18

Pasé unas horas en esto también ... y acepto que FLAG_ACTIVITY_CLEAR_TOP suena como lo que querría: borrar toda la pila, excepto la actividad que se está iniciando, 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ás lanzando ya está en la pila; cuando la actividad no está allí, la bandera no hace nada.

¿Qué hacer? Ponga en marcha la actividad en la pila con FLAG_ACTIVITY_NEW_TASK, que convierte esa actividad en el inicio de una nueva tarea en la pila del historial. A continuación, agregue el indicador FLAG_ACTIVITY_CLEAR_TOP.

Ahora, cuando FLAG_ACTIVITY_CLEAR_TOP va a buscar la nueva actividad en la pila, estará allí 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á asociada 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(); 
} 
+0

¿quiere decir CLEAR_TASK en lugar de CLEAR_TOP? –

0

me pareció demasiado simple truco sólo que este complemento nuevo elemento en AndroidManifest como: -

<activity android:name=".activityName" 
      android:label="@string/app_name" 
      android:noHistory="true"/> 

la android:noHistory aclarará su actividad no deseada de la pila.

+0

Este enfoque puede causar problemas en Android 6.0+, si solicita permiciones en esta Actividad. –

13

Con versión más reciente de Android> = 16 API utilización finishAffinity()

enfoque es adecuado para> = 16 API.

Intent mIntent = new Intent(mContext,MainActivity.class); 
finishAffinity(); 
startActivity(mIntent); 
  • Su es igual a comenzar nueva actividad, y borrar todos los pila.
  • O reinicie a MainActivity/FirstActivity.
+1

Esto hizo el truco, las banderas werent trabajando en 4.x.x para mí y esto funcionó a la perfección! Gracias –

-1

En ocasiones, su emulador de Android puede fallar al conectar la herramienta eclipse DDMS y solicitar que adb inicie manualmente. En ese caso, puede iniciar o detener el adb usando el símbolo del sistema.

+1

Algunas veces, su emulador de Android podría fallar al conectar la herramienta eclipse DDMS y solicitar que adb comience manualmente. En ese caso, puede iniciar o detener el adb usando el símbolo del sistema. Intención i = new Intent (OldActivity.this, NewActivity.class); // establecer la nueva tarea y borrar indicadores i.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK) startActivity (i); – RajeshkumarG

2

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(); 
1

Intención i = new intención (MainPoliticalLogin.this, MainActivity.class); i.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

     startActivity(i); 
Cuestiones relacionadas