2010-12-03 10 views
64

He leído varias publicaciones sobre cómo usar esto, pero me falta algo, ya que no funciona para mí. Mi actividad A tiene launchmode = "singleTop" en el manifiesto. Inicia la actividad B, con launchmode = "singleInstance". La actividad B abre un navegador y recibe e intenta regresar, razón por la cual es SingleInstance. Estoy tratando de anular el botón Atrás para que el usuario vuelva a la actividad A, y luego presione Atrás para salir de la actividad, en lugar de regresar a la actividad B nuevamente.¿Cómo se usa Intent.FLAG_ACTIVITY_CLEAR_TOP para borrar la pila de actividades?

// activity B 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR 
    && keyCode == KeyEvent.KEYCODE_BACK 
    && event.getRepeatCount() == 0) onBackPressed(); 
return super.onKeyDown(keyCode, event); 
} 
@Override 
public void onBackPressed() { 
startActivity(new Intent(this, UI.class) 
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)); 
return; 
} 

Después de volver del navegador, la pila es ... A, B, navegador, B

espero que este código para cambiar la pila para ... Un ... así que presionar una vez más lleva al usuario a la pantalla de inicio.

En su lugar, parece cambiar la pila a ... A, B, navegador, B, A ... como si esas banderas no estuvieran allí.

Intenté llamar a finish() en la actividad B después de iniciar la actividad, pero luego el botón Atrás me lleva de vuelta al navegador.

¿Qué me estoy perdiendo? ¡Gracias!

Respuesta

55

@bitestar tiene la solución correcta, pero hay un paso más:

fue escondido en la documentación, sin embargo, debe cambiar el launchMode del Activity a cualquier cosa que no sea standard. De lo contrario, se destruirá y se volverá a crear en lugar de restablecerse en la parte superior.

+38

En realidad ... 'Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP' hará solo eso. –

+0

Verifique la solución de Steel_fedex para su ejemplo. – Darpan

1

FLAG_ACTIVITY_NEW_TASK es el problema aquí que inicia una nueva tarea. Solo elimínelo & ha terminado.

Bueno, te recomendamos leer lo que cada bandera hace antes de trabajar con ellos

Leer this & Intent Flags here

+1

Yo ya había leído la bandera, y que sonaba como lo que necesitaba. Independientemente, eliminar FLAG_ACTIVITY_NEW_TASK no tiene ningún efecto en el resultado. Sigue siendo un ciclo infinito de bucle invertido ... A-> B, vuelve a A, regresa a B, vuelve a A ... – piusvelte

+0

¿Estás seguro de por qué estás utilizando B como única instancia? La actividad AA "instancia única" actúa como si FLAG_ACTIVITY_NEW_TASK estaba en el intento. Compruebe http://developer.android.com/guide/topics/fundamentals.html – 100rabh

+0

B necesita recibir el intento devuelto desde el navegador. Traté de cambiar el modo de lanzamiento a singleTask, y eso todavía funciona, pero el bucle de retroceso todavía se produce. – piusvelte

1

problema Inicialmente también tuve conseguir FLAG_ACTIVITY_CLEAR_TOP para trabajar. Finalmente lo conseguí para trabajar usando el valor de esto (0x04000000). Parece que hay un problema de Eclipse/compilador. Pero desafortunadamente la actividad superviviente se reinicia, que no es lo que quiero. Parece que no hay una solución fácil.

98

He comenzado la Actividad A-> B-> C-> D. Cuando se presiona el botón Atrás en la Actividad DI quiero ir a la Actividad A. Como A es mi punto de partida y por lo tanto ya está en la pila, todas las actividades en la parte superior de A se borran y no se puede volver a ninguna otra Actividad de A.

Esto funciona realmente en mi código:

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     Intent a = new Intent(this,A.class); 
     a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
     startActivity(a); 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
}  
+0

Esta solución está cerrando todas las actividades intermedias, pero también reiniciando la RootActivity. Puede consultar la solución de @ Steel_Fedex a continuación. hace lo mismo, pero no reinicia RootActivity. – Darpan

+0

Esta es la mejor solución para mi caso. En realidad ** quiero ** que la actividad raíz se inicie de nuevo –

18

Para ello, utilizo FLAG_ACTIVITY_CLEAR_TOP bandera para iniciar Intent
(sin FLAG_ACTIVITY_NEW_TASK)

y launchMode = "singleTask" en el manifiesto lanzado para la actividad.

Parece que funciona como lo necesito - la actividad no se reinicia y todas las demás actividades están cerradas.

+0

He comprobado que la Solución de Bitster no funciona. Mientras que esta solución funcionó. RootActivity no se reinició. – Darpan

+0

Elija sus palabras más sabiamente ¡La solución de Bitestar realmente funciona! – bitestar

+0

singleTask funciona para mí , entonces la actividad no recrear y manejar el evento en onNewIntent. –

2

Sé que ya hay una respuesta aceptada, pero no veo cómo funciona para el OP porque no creo que FLAG_ACTIVITY_CLEAR_TOP tenga sentido en su caso particular. Esa marca solo es relevante con actividades en la misma tarea . Según su descripción, cada actividad está en su propia tarea: A, B y el navegador.

Algo que quizás lo está tirando es que A es singleTop, cuando debería ser singleTask. Si A es singleTop, y B inicia A, entonces se creará una nueva A porque A no está en la tarea de B. A partir de la documentación para singleTop:

"Si una instancia de la actividad ya existe en la parte superior de la tarea actual, las rutas del sistema de la intención de esa instancia ..."

Puesto que B comienza A, la tarea actual es la tarea de B, que es para una sola instancia y, por lo tanto, no puede incluir A. Use singleTask para lograr el resultado deseado allí porque entonces el sistema encontrará la tarea que tiene A y traerá esa tarea al primer plano.

Por último, después de que B ha iniciado A, y el usuario presiona desde A, OP no quiere ver B ni el navegador. Para lograr esto, llamar a finish() en B es correcto; nuevamente, FLAG_ACTIVITY_CLEAR_TOP no eliminará las otras actividades en la tarea de A porque sus otras actividades están todas en tareas diferentes. Sin embargo, la pieza que le faltaba era que B también debería usar FLAG_ACTIVITY_NO_HISTORY cuando dispara el intento para el navegador. Nota: si el navegador ya se está ejecutando incluso antes de iniciar la aplicación del OP, entonces, por supuesto, verá el navegador al presionar desde A. Entonces, para realmente probar esto, asegúrese de abandonar el navegador antes de iniciar la aplicación .

9

Aunque esta pregunta ya tiene suficientes respuestas, pensé que alguien podría querer saber por qué esta bandera obras de esta manera peculiar, Esto es lo que he encontrado en Android documentation

La instancia actualmente en ejecución de la actividad B en el El ejemplo anterior recibirá el nuevo intento que está comenzando aquí en su método onNewIntent(), o se terminará y se reiniciará con el nuevo intento.

Si ha declarado que su modo de lanzamiento es "múltiple" (el valor predeterminado) y no ha configurado FLAG_ACTIVITY_SINGLE_TOP en el mismo intento, entonces se terminará y se volverá a crear; para todos los demás modos de ejecución o si se establece FLAG_ACTIVITY_SINGLE_TOP, este Intent se entregará a la instancia actual onNewIntent().


Por lo tanto, tampoco,
. Cambia el launchMode de la Actividad A a algo más del estándar (es decir, singleTask o algo así). Luego, su bandera FLAG_ACTIVITY_CLEAR_TOP no se reiniciará su actividad A.

o,

. Use Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP como su bandera. Entonces funcionará de la manera que desees.

0

llamé activity_name.this.finish() después de comenzar una nueva intención y funcionó para mí.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK" 

Pero no funcionará para mí ...No estoy sugiriendo esta solución para su uso, pero si la configuración del indicador no funciona para usted, puede intentarlo ... Pero aún así lo recomiendo, no lo use

0

Agregue android: noHistory = "true" en el archivo de manifiesto.

<manifest > 
     <activity 
      android:name="UI" 
      android:noHistory="true"/> 

</manifest> 
1

utilizo tres banderas para resolver el problema:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| 
       Intent.FLAG_ACTIVITY_CLEAR_TASK | 
       Intent.FLAG_ACTIVITY_NEW_TASK); 
Cuestiones relacionadas