Come si utilizza Intent.FLAG_ACTIVITY_CLEAR_TOP per cancellare lo Stack delle attività?


85

Ho letto diversi post sull'utilizzo di questo, ma deve mancare qualcosa perché non funziona per me. La mia attività A ha launchmode = "singleTop" nel manifest. Inizia l'attività B, con launchmode = "singleInstance". L'attività B apre un browser e riceve e restituisce, motivo per cui è singleInstance. Sto provando a sovrascrivere il pulsante Indietro in modo che l'utente venga rimandato all'attività A e possa quindi premere Indietro per abbandonare l'attività, anziché tornare di nuovo all'attività B.

// 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;
}

Dopo essere tornato dal browser, lo stack è ... A, B, Browser, B

Mi aspetto che questo codice cambi lo stack in ... A ... in modo che premendo ancora una volta indietro l'utente torni alla schermata principale.

Invece sembra cambiare lo stack in ... A, B, Browser, B, A ... come se quei flag non ci fossero.

Ho provato a chiamare finish () nell'attività B dopo startActivity, ma poi il pulsante indietro mi riporta di nuovo al browser!

Cosa mi manca? Grazie!

Risposte:


72

@bitestar ha la soluzione corretta, ma c'è un altro passaggio:

Era nascosto nei documenti, tuttavia è necessario modificare il launchModedi Activityin qualcosa di diverso da standard. Altrimenti verrà distrutto e ricreato invece di essere ripristinato all'inizio.


52
In realtà ... Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPfarà proprio questo.
Derk-Jan

Controlla la soluzione di Steel_fedex per il suo esempio.
Darpan

2
quindi dove diavolo è la soluzione di Steel_fedex ?!
ChangWon Jeong Juicycool

112

Ho iniziato l'attività A-> B-> C-> D. Quando si preme il pulsante indietro sull'attività DI voglio andare all'attività A. Poiché A è il mio punto di partenza e quindi già in pila tutte le attività in cima ad A vengono cancellate e non puoi tornare a nessun'altra attività da A .

Questo funziona effettivamente nel mio codice:

@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);
}       

4
Questa soluzione sta chiudendo tutte le attività di intermediazione; ma anche riavviare RootActivity. Puoi controllare la soluzione di @ Steel_Fedex di seguito. Fa lo stesso, ma non riavvia RootActivity.
Darpan

Questa è la soluzione migliore per il mio caso. In realtà voglio che l'attività di root ricominci
Tash Pemhiwa

24

Per questo, uso la FLAG_ACTIVITY_CLEAR_TOPbandiera per iniziare Intent
(senza FLAG_ACTIVITY_NEW_TASK)

e launchMode = "singleTask"in manifest per l'attività avviata.

Sembra che funzioni come necessario: l'attività non si riavvia e tutte le altre attività vengono chiuse.


Ho controllato, la soluzione di Bitster non funziona. Mentre questa soluzione ha funzionato. RootActivity non è stato riavviato.
Darpan

Scegli le tue parole in modo più saggio. La soluzione Bitestar funziona davvero!
Jesper Bischoff-Jensen

singleTask funziona per me, quindi Activity non verrà ricreato e gestirà l'evento in onNewIntent.
Jishi Chen

11

Sebbene questa domanda abbia già risposte sufficienti, ho pensato che qualcuno avrebbe voluto sapere perché questo flag funziona in questo modo particolare, questo è quello che ho trovato nella documentazione di Android

L'istanza dell'attività B attualmente in esecuzione nell'esempio precedente riceverà il nuovo intento che stai iniziando qui nel suo metodo onNewIntent () o sarà essa stessa terminata e riavviata con il nuovo intento.

Se ha dichiarato che la sua modalità di avvio è "multipla" (impostazione predefinita) e non hai impostato FLAG_ACTIVITY_SINGLE_TOP nello stesso intento, verrà terminato e ricreato; per tutte le altre modalità di avvio o se FLAG_ACTIVITY_SINGLE_TOP è impostato, questo Intent verrà consegnato all'istanza corrente onNewIntent ().


Quindi, entrambi,
1 . Cambia il valore launchModedell'attività A in qualcos'altro rispetto allo standard (cioè singleTasko qualcosa del genere). Quindi la tua bandiera FLAG_ACTIVITY_CLEAR_TOPnon riavvierà la tua attività A.

o,

2 . Usa Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOPcome bandiera. Quindi funzionerà nel modo desiderato.


8

Uso tre flag per risolvere il problema:

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

4

Aggiungi android: noHistory = "true" nel file manifest.

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

</manifest>

La prima volta che vedo questa bandiera, ma ha funzionato per il mio caso, grazie
vlasentiy

3

ho chiamato activity_name.this.finish()dopo aver iniziato un nuovo intento e ha funzionato per me.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Ma non funzionerà per me ... Non sto suggerendo questa soluzione per l'uso ma se l'impostazione del flag non funziona per te, puoi provare questo..Ma comunque ti consiglio di non usarlo


2

So che c'è già una risposta accettata, ma non vedo come funziona per l'OP perché non penso che FLAG_ACTIVITY_CLEAR_TOP sia significativo nel suo caso particolare. Questo flag è rilevante solo con le attività nella stessa attività . In base alla sua descrizione, ogni attività è nel proprio compito : A, B e il browser.

Qualcosa che forse lo sta sbalordendo è che A è singleTop, quando dovrebbe essere singleTask. Se A è singleTop e B inizia A, verrà creato un nuovo A perché A non è nel compito di B. Dalla documentazione per singleTop:

"Se un'istanza dell'attività esiste già all'inizio dell'attività corrente , il sistema instrada l'intento a quell'istanza ..."

Poiché B avvia A, l'attività corrente è l'attività di B, che è per una singola istanza e quindi non può includere A. Usa singleTask per ottenere il risultato desiderato lì perché quindi il sistema troverà l'attività che ha A e porterà quell'attività in primo piano.

Infine, dopo che B ha avviato A e l'utente preme indietro da A, l'OP non vuole vedere né B né il browser. Per ottenere ciò, chiamare finish () in B è corretto; ancora una volta, FLAG_ACTIVITY_CLEAR_TOP non rimuoverà le altre attività nell'attività di A perché le sue altre attività sono tutte in attività diverse. Il pezzo che gli mancava, però, è che B dovrebbe anche usare FLAG_ACTIVITY_NO_HISTORY quando attiva l'intento per il browser. Nota: se il browser è già in esecuzione anche prima di avviare l'applicazione dell'OP, ovviamente vedrai il browser quando premi indietro da A. Quindi, per testarlo davvero, assicurati di uscire dal browser prima di avviare l'applicazione.


1

FLAG_ACTIVITY_NEW_TASK è il problema qui che avvia una nuova attività. Rimuovila e hai finito.

Bene, ti consiglio di leggere cosa fa ogni Flag prima di lavorarci

Leggi questo & Intent Flags qui


1
Ho letto la bandiera e suonava come quello di cui avevo bisogno. Indipendentemente da ciò, la rimozione di FLAG_ACTIVITY_NEW_TASK non ha alcun effetto sul risultato. È ancora un ciclo infinito di pulsanti indietro ... A-> B, torna in A, torna in B, torna in A ...
piusvelte

Sei sicuro del motivo per cui stai utilizzando B come singleInstance? L'attività "singleInstance" di AA si comporta come se FLAG_ACTIVITY_NEW_TASK fosse nell'intent.Check developer.android.com/guide/topics/fundamentals.html
100rabh

B deve ricevere l'intento richiamato dal browser. Ho provato a cambiare la modalità di avvio in singleTask, e funziona ancora, ma il ciclo del pulsante Indietro si verifica ancora.
piusvelte

Penso che non abbia funzionato perché hai usato FLAG_ACTIVITY_NEW_TASK lì. Meglio usare solo FLAG_ACTIVITY_CLEAR_TOP ed evitare di usare né singleTask né singleInstance
100rabh

1
Penso che dovrebbe essere una soluzione funzionante, se aggiungi Intent.FLAG_ACTIVITY_SINGLE_TOPper impedire la ricreazione
yonojoy

1

Inizialmente ho anche avuto problemi a far funzionare FLAG_ACTIVITY_CLEAR_TOP. Alla fine l'ho fatto funzionare usando il valore di esso (0x04000000). Quindi sembra che ci sia un problema con Eclipse / compilatore. Ma sfortunatamente l'attività sopravvissuta viene riavviata, che non è quello che voglio. Quindi sembra che non ci sia una soluzione facile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.