Android: Cancella stack attività


132

Sto avendo diverse attività nella mia applicazione. e il flusso è molto complicato. Quando faccio clic sull'applicazione Logout naviga per accedere alla schermata di accesso e da lì l'utente può uscire dal pulsante Annulla (chiamata system.exit(0))

quando esco o pulsante indietro, il sistema invoca un'attività dallo stack :( come posso cancellare tutte le attività nello stack quando raggiungo la schermata di accesso? la chiamata finish()non è pratica in quanto ci sono così tante attività e alcune attività non dovrebbero essere chiuse quando sono attivi come l'attività di invocazione della fotocamera nativa.

validateuser logoutuser = new validateuser();
logoutuser.logOut();
Intent loginscreen = new Intent(homepage.this, Login2.class);
(homepage.this).finish();
loginscreen.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(loginscreen);


Risposte:


339

Molti di voi hanno torto. Se si desidera chiudere lo stack di attività esistente indipendentemente da ciò che è presente e creare una nuova radice, il set corretto di flag è il seguente:

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

Dal documento :

public static final int FLAG_ACTIVITY_CLEAR_TASK
Aggiunto nel livello API 11

Se impostato in un Intento passato a Context.startActivity(), questo flag provocherà la cancellazione di qualsiasi attività esistente che sarebbe associata all'attività prima dell'avvio dell'attività. Cioè, l'attività diventa la nuova radice di un'attività altrimenti vuota e tutte le vecchie attività sono terminate. Questo può essere usato solo insieme a FLAG_ACTIVITY_NEW_TASK.


Ha funzionato perfettamente. Grazie. Stranamente non ha dato errori con minSDK = 9.
Mahm00d,

Francamente non ho mai usato questa funzionalità, resuscect dopo crash, ecc., E piuttosto concentrato sulla risoluzione dei problemi che hanno causato l'incidente)
Cynichniy Bandera,

La stessa funzionalità fornisce anche IntentCompat.makeRestartActivityTaskdalla libreria di supporto.
sealskej,

L'aggiunta di solo quei due flag lascia indietro la traccia dello stack di attività (inizia sopra quella precedente), quindi ha aggiunto Intent.FLAG_ACTIVITY_CLEAR_TOP che riavvia semplicemente l'applicazione e poi esce completamente. Non ho aggiunto alcuna bandiera alle attività esplicitamente però. Quale potrebbe essere il problema?
Farid,

1
Uno dei migliori inizi: "Molti di voi hanno torto".
nibbana,

31

Quando chiami startActivityl'ultima attività puoi sempre usare

Intent.FLAG_ACTIVITY_CLEAR_TOP

come una bandiera su quell'intento.

Leggi di più sulla bandiera qui .


anche questo non aiuta. Ho appena richiamato un'attività dat che non termina con finish (); :(
Jay Mayu,

Immagino che FLAG_ACTIVITY_CLEAR_TOP cancelli le attività in alto. Il mio problema sono le attività sul fondo :(
Jay Mayu,

Immagino che dipenda da come sia effettivamente il flusso. Dovresti leggere di più qui: developer.android.com/reference/android/content/… e developer.android.com/guide/topics/fundamentals/…
David Olsson,

7
Grazie per aver mostrato le risorse corrette. l'errore che ho fatto è stato chiudere l'attività di accesso. Non dovrei chiuderlo. Quando l'attività è stata caricata per prima. quindi quando lo richiamo utilizzando il flag Clear_top, l'attività di accesso cancella tutte le attività in alto. poiché il login è la prima attività di accesso, cancella tutte le attività iniziate dopo. quindi il bingo ha funzionato :)
Jay Mayu il

13
Dalla documentazione, FLAG_ACTIVITY_CLEAR_TOP cancella lo stack solo se l'attività specifica "già in esecuzione nell'attività corrente"
AlikElzin-kilaka

16

Ecco un semplice metodo di supporto per l'avvio di una nuova attività come nuova attività principale che funziona dal livello API 4 fino alla versione corrente 17:

static void startNewMainActivity(Activity currentActivity, Class<? extends Activity> newTopActivityClass) {
    Intent intent = new Intent(currentActivity, newTopActivityClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        intent.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK which is only available from API level 11
    currentActivity.startActivity(intent);
}

chiamalo così dalla tua attuale attività:

startNewMainActivity(this, MainActivity.class);

1
Non potresti sempre usare intent.addFlags (0x8000); e semplificarlo?
Assapora il

Dato che questo flag è stato introdotto per la prima volta in Honeycomb, non ho idea di quale possa essere l'implicazione sulle versioni precedenti. Quindi, ero io a essere precucili. Ma credo che la rimozione del condizionale non dovrebbe essere un problema.
whlk,

1
vuoi aggiungere quel flag quando il livello API è <11, quindi devi fare Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMBaltrimenti intent.addFlags(0x8000);non verrà mai aggiunto
Cappello di paglia

Sto facendo in modo che l'utente esegua molte attività una dopo l'altra attraverso gli intenti. Devo fare qualcosa per assicurarmi che l'app non si blocchi con troppe attività in pila? Grazie!
Ruchir Baronia,

9

Cancella attività Backstate con il codice seguente:

Intent intent = new Intent(Your_Current_Activity.this, Your_Destination_Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Fatto


Sto facendo in modo che l'utente esegua molte attività una dopo l'altra attraverso gli intenti. Devo fare qualcosa per assicurarmi che l'app non si blocchi con troppe attività in pila? Grazie!
Ruchir Baronia,

@RuchirBaronia, Se vai A -> B -> C -> D -> E -> F -> G -> H, ora H -> Scrivo il mio codice di quando sarò Ultima attività dopo aver premuto il pulsante Indietro l'app si chiuderà perché l'app non ha attività nel backstate, spero che questo ti possa aiutare.
Hiren Patel,

Devo farlo però? Cosa succederà se non pulisco mai lo stack di attività?
Ruchir Baronia,

@RuchirBaronia, Backpress: H -> G -> F -> E -> D -> C -> B -> A
Hiren Patel

Ma qualche volta mostra uno schermo bianco mentre si chiama una nuova attività. Ho da risolvere questo?
Sagar

4

Nel mio caso, anche LoginActivity è stato chiuso. Di conseguenza,

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

non ha aiutato.

Tuttavia, impostazione

Intent.FLAG_ACTIVITY_NEW_TASK

mi ha aiutato.


Sto facendo in modo che l'utente esegua molte attività una dopo l'altra attraverso gli intenti. Devo fare qualcosa per assicurarmi che l'app non si blocchi con troppe attività in pila? Grazie!
Ruchir Baronia,

3
Intent intent = new Intent(LoginActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //It is use to finish current activity
startActivity(intent);
this.finish();

1
perché stai usando entrambi this.finish()e setFlags()anche per cancellare l'attività corrente?
Sagar

3

Ho notato che hai chiesto una soluzione su cui non fare affidamento finish() , ma mi chiedo se ciò possa aiutare comunque.

Ho monitorato se un flag di uscita viene generato con una variabile di classe statica, che sopravvive all'intera durata dell'app. In ogni attività pertinenteonResume() , utilizzare

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

La classe ExitHelper

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

Diciamo in mainActivity, un utente preme un pulsante per uscire - è possibile impostare ExitHelper.isExitFlagRaised = true; e quindi finish(). Successivamente, verranno completate anche altre attività rilevanti che vengono riprese automaticamente.


cosa succederà se uso il codice in MainActivity onresume () e poi torno alla mainattività dalla seconda attività onbackpress
Mithu

3

Questa decisione funziona bene:

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

Ma la nuova attività si avvia a lungo e vedrai lo schermo bianco qualche volta. Se questo è fondamentale, utilizzare questa soluzione alternativa:

public class BaseActivity extends AppCompatActivity {

    private static final String ACTION_FINISH = "action_finish";

    private BroadcastReceiver finisBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        registerReceiver(finisBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                finish();
            }
        }, new IntentFilter(ACTION_FINISH));
    }

    public void clearBackStack() {
        sendBroadcast(new Intent(ACTION_FINISH));
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(finisBroadcastReceiver);
        super.onDestroy();
    }
}

Come usarlo:

public class ActivityA extends BaseActivity {

    // Click any button
    public void startActivityB() {
        startActivity(new Intent(this, ActivityB.class));
        clearBackStack();
    }
}

Svantaggio: tutte le attività che devono essere chiuse nello stack devono estendere BaseActivity


2

Per gli sviluppatori Xamarin, è possibile utilizzare:

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);

1

Utilizzando Kotlin:

È possibile impostare il flag direttamente utilizzando il metodo setter. In Kotlin orè la sostituzione per Java bit a bit o |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Se si prevede di utilizzarlo regolarmente, creare una funzione di estensione Intento

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

È quindi possibile chiamare direttamente questa funzione prima di iniziare l'intento

intent.clearStack()
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.