Termina tutte le attività precedenti


368

La mia applicazione ha le seguenti schermate di flusso:

Home->screen 1->screen 2->screen 3->screen 4->screen 5

Ora ho un log out pulsante comune in ogni schermata

( Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)

Voglio che quando l'utente fa clic sul pulsante di disconnessione (da qualsiasi schermata), tutte le schermate saranno terminate e Log insi aprirà una nuova schermata .

Ho provato quasi tutti FLAG_ACTIVITYa raggiungere questo obiettivo. Vado anche attraverso alcune risposte in StackOverflow, ma non riesco a risolvere il problema. La mia applicazione è su Android 1.6, quindi non posso usarlaFLAG_ACTIVITY_CLEAR_TASK

C'è un modo per risolvere il problema?


Gestisci le tue attività nidificate usando startActivityForResult?
woodshy,

no. Tutte le attività vengono avviate con startActivity.
Tanmay Mandal,

Sto usando attività nidificate mentre il merluzzo bianco esegue finishaffinitytask () in attività nidificate. cambia il comportamento? come a volte sto ricevendo un errore nella consegna del risultato ResultInfo quando viene eseguito finishaffinitytask.
Ripal Tamboli,

Controlla questa risposta, ti aiuterà sicuramente stackoverflow.com/a/25159180/2732632
Kimmi Dhingra

3
Android 21 ha introdotto Activity.finishAndRemoveTask ().
Joseph Johnson,

Risposte:


543

Uso:

Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Questo cancellerà tutte le attività in cima a casa.

Supponendo che tu stia finendo la schermata di accesso quando l'utente accede e viene creata la home e successivamente tutte le schermate da 1 a 5 sopra quella. Il codice che ho pubblicato ti riporterà alla schermata principale completando tutte le altre attività. Puoi aggiungere un extra nell'intento e leggerlo nell'attività della schermata principale e finirlo anche (forse riavviare la schermata di accesso da lì o qualcosa del genere).

Non sono sicuro ma puoi anche provare ad accedere con questo flag. Non so come verranno ordinate le attività in quel caso. Quindi non so se cancellerà quelli sotto lo schermo in cui ti trovi, incluso quello in cui sei attualmente, ma è sicuramente la strada da percorrere.

Spero che sia di aiuto.


L'utente sta mostrando la sua prima schermata come schermata principale, questo è il problema principale.
Tanmay Mandal,

così come ho la mia risposta è necessario tornare alla schermata principale e finirla. quindi il processo chiama l'intento sopra da qualsiasi schermata. ricevere l'intento nella schermata Home e lanciare immediatamente un intento verso il login e finire a casa dopo il metodo startActivity. puoi anche sovrascrivere l'animazione in sospeso su null per entrare e uscire in modo che non mostri la transizione (lo faccio perché sembra un po 'più veloce) .Quindi dovrebbe funzionare bene per ciò di cui hai bisogno.
DArkO,

10
Invece di dichiarare l'attività come singleInstance, considera l'utilizzo FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOPcome flag per l'intento. Ciò finirà le attività intermedie e avvierà (o riporterà in primo piano) l'attività desiderata.
CommonsWare,

13
@ CommonsWare L'aggiunta intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);alla mia attività non mi ha aiutato. Non ha terminato le attività intermedie. Quando torno indietro dalla schermata di accesso posso vedere le attività precedenti Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);. Ecco il mio codice .
Tanmay Mandal,

26
questo codice cancella solo lo stack delle attività principali, per cancellare tutte le attività intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
Ajay Venugopal

318

Puoi provare Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. Cancella completamente tutte le attività precedenti e avvia nuove attività.


11
La soluzione corretta, ma solo API 11+
riwnodennyk

Ho finito per usare questo flag extra in quanto non causa un ritardo quando mostra l'attività principale (non lo riavvierà quindi è molto più veloce).
Maurizio,

2
@riwnodennyk perché API 11+?
Muhammad Babar,

17
Usa IntentCompat.FLAG_ACTIVITY_CLEAR_TASK per le versioni pre 11
Steven Pena

2
@ono Sì. Dovrebbe essere tutto ciò di cui hai bisogno. Assicurati che la modalità di avvio dell'attività di destinazione sia impostata come "singleTask" nel manifest.
Steven Pena,

137

Prima di avviare la tua nuova attività, aggiungi semplicemente il seguente codice:

finishAffinity();

O se vuoi che funzioni nelle versioni precedenti di Android:

ActivityCompat.finishAffinity(this);

12
ActivityCompat.finishAffinity (questo); chiama activity.finish () per api <16. Quindi non funzionerà.
Aamir Abro,

1
@Beto Caldas, ho confermato io stesso il codice sorgente, non funzionerà per API <16 come menzionato da AamirAbro.
Finirà

39

Quando l'utente desidera uscire da tutte le attività aperte , deve premere un pulsante che carica la prima attività in esecuzione all'avvio dell'applicazione, cancellare tutte le altre attività, quindi terminare l'ultima attività rimanente. Far eseguire il codice seguente quando l'utente preme il pulsante di uscita. Nel mio caso, LoginActivityè la prima attività nel mio programma da eseguire.

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

Il codice sopra cancella tutte le attività ad eccezione di LoginActivity. Quindi inserisci il seguente codice all'interno di LoginActivity's onCreate(...), per ascoltare quando LoginActivityviene ricreato e il segnale' EXIT 'è stato passato:

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();  
}

Perché creare un pulsante di uscita in Android è così difficile?

Android si sforza di scoraggiarti dall'avere un pulsante "esci" nella tua applicazione, perché vogliono che l'utente non si preoccupi mai se i programmi che usano sono in esecuzione o meno in background.

Gli sviluppatori del sistema operativo Android vogliono che il tuo programma sia in grado di sopravvivere a uno spegnimento e uno spegnimento imprevisti del telefono e quando l'utente riavvia il programma, riprendono da dove erano stati interrotti. In questo modo l'utente può ricevere una telefonata mentre utilizza l'applicazione e aprire le mappe che richiedono la liberazione dell'applicazione per ulteriori risorse.

Quando l'utente riprende l'applicazione, riprende da dove aveva interrotto senza interruzioni. Questo pulsante di uscita sta consumando energia dal manager delle attività, causando potenzialmente problemi con il ciclo di vita del programma Android gestito automaticamente.


31
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Funzionerà con tutte le versioni di Android. Dove IntentCompatla classe è stata aggiunta nella libreria di supporto Android.


IntentCompat.FLAG_ACTIVITY_CLEAR_TASKnon è riconosciuto, utilizzare Intentinvece di IntentCompat.
CoolMind,

30

Utilizzare quanto segue per l'attività

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

rimuovere il flag CLEAR_TASK per l'utilizzo dei frammenti.

Spero che questo possa essere utile per alcune persone.


24

Immagino di essere in ritardo, ma c'è una risposta semplice e breve. Esiste un metodo finishAffinity () in Attività che completerà l'attività corrente e tutte le attività principali, ma funziona solo in Android 4.1 o versioni successive.

Per API 16+, utilizzare

finishAffinity();

Per meno di 16 anni, utilizzare

ActivityCompat.finishAffinity(YourActivity.this);

Spero che sia d'aiuto!


21

Da developer.android.com :

public void finishAffinity ()

Aggiunto nel livello API 16

Termina questa attività e tutte le attività immediatamente sottostanti nell'attività corrente che hanno la stessa affinità. Questo è in genere utilizzato quando un'applicazione può essere avviata su un'altra attività (ad esempio da un ACTION_VIEW di un tipo di contenuto che comprende) e l'utente ha utilizzato la navigazione verso l'alto per uscire dall'attività corrente e accedere alla propria attività. In questo caso, se l'utente è passato ad altre attività della seconda applicazione, tutte queste dovrebbero essere rimosse dall'attività originale come parte del cambio di attività.

Si noti che questa finitura non consente di fornire risultati all'attività precedente e verrà generata un'eccezione se si sta tentando di farlo.


19

Nota a margine, utile sapere
Questa risposta funziona ( https://stackoverflow.com/a/13468685/7034327 )

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();

mentre questo non funziona

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

.setFlags() sostituisce eventuali flag precedenti e non aggiunge alcun nuovo flag mentre lo .addFlags()fa.

Quindi anche questo funzionerà

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Grande spiegazione sulla differenza tra setFlag vs addFlag, grazie
Pelanes,

13

Se la tua applicazione ha una versione minima di sdk 16, puoi usare finishAffinity ()

Termina questa attività e tutte le attività immediatamente sottostanti nell'attività corrente che hanno la stessa affinità.

Questo funziona per me Nella schermata Pagamento principale rimuovi tutte le attività di back-stack,

@Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29


10

Una soluzione che ho implementato per questo (penso di averlo trovato su Stack Overflow da qualche parte, ma non ricordo, quindi grazie a chi l'ha fatto in primo luogo):

Da una qualsiasi delle tue attività fai questo:

// Clear your session, remove preferences, etc.
Intent intent  = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Quindi in LoginActivity, sovrascrivi onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

3
Di solito è una pessima idea, anche se potrebbe funzionare, introduce un punto di contatto che potrebbe rompersi in futuro e sarà difficile eseguire il debug. Te lo dico per esperienza :)
Martin Marconcini l'

10

Per il pulsante di logout sull'ultima schermata dell'app, utilizzare questo codice sul listener del pulsante di logout per completare tutte le attività precedenti aperte e il problema è stato risolto.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}

8
    Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();

6
perché FLAG_ACTIVITY_CLEAR_TASK due volte?
Choletski,

1
Da quello che ho capito, .setFlags sostituisce i flag precedenti e non aggiunge alcun flag. .addFlags è quello che volevi usare presumo? Causa tutto il codice sopra i1.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); viene spazzato via
iOSAndroidWindowsMobileAppsDev

addFlags Funziona per me
Jamil,

1
setFlagssostituirà tutti i precedenti, quindi l'ultimo setFlagsè valido solo, i precedenti vengono sostituiti. Quindi non è necessario chiamarei1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
mtrakal

8

ho lo stesso problema che puoi usare IntentCompat, in questo modo:

import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

questo codice funziona per me.

API Android 17


8

Nel mio caso utilizzo la finishAffinity()funzione nell'ultima attività come:

finishAffinity()
startHomeActivity()

Spero ti sia utile.



6

Accedi-> Home-> schermata 1-> schermata 2-> schermata 3-> schermata 4-> schermata 5

sullo schermo 4 (o qualsiasi altro) ->

StartActivity (Accedi)
con
FLAG_ACTIVITY_CLEAR_TOP


2
Quando premo il pulsante Indietro, tutte le attività precedenti vengono visualizzate nell'ordine in cui erano .queste attività devono essere chiuse, quando si fa clic sul pulsante di logout ci sarà una sola attività nello stack e quella sarà l'attività di accesso. schermata di accesso L'utente inizia dalla schermata principale.
Tanmay Mandal,

6

per API> = da 15 a API 23 soluzione semplice.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);

Elabora la tua risposta in modo che tutti possano beneficiarne.
Shubhamoy,

5

Se stai utilizzando le startActivityForResult()tue attività precedenti, esegui l'override OnActivityResult()e chiama il finish();metodo al suo interno in tutte le attività .. Questo farà il lavoro ...


No, sto startActivitysolo usando .
Tanmay Mandal,

Sarà difficile mantenere onActivityResultogni attività. Ho implementato il suggerimento di DArkO e raggiunto il mio obiettivo e grazie per l'aiuto.
Tanmay Mandal,

3

Quando l'utente fa clic sul pulsante di disconnessione, quindi scrive il seguente codice:

Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

E anche quando dopo il login se chiami nuova attività non usare finish ();


2

Semplicemente, quando si passa dalla schermata di accesso, non quando si finisce la schermata di accesso.

E poi in tutte le attività di inoltro, utilizzalo per il logout:

final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);

Funziona perfettamente.


1

Se si accede l'utente screen 1e da lì si passa alle altre schermate, utilizzare

Intent intent = new Intent(this, Screen1.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Quando premo il pulsante Indietro, tutte le attività precedenti vengono visualizzate nell'ordine in cui erano .queste attività devono essere chiuse, quando si fa clic sul pulsante di disconnessione ci sarà solo un'attività nello stack e quella sarà l'attività di accesso.
Tanmay Mandal,

Se si desidera questo comportamento, è necessario eseguire l'override onKeyDowne onBackPressed(o onKeyDown, se si desidera supportare le versioni di Android <2.0) in ciascuna delle proprie attività (tranne quella di accesso), e startActivity(login)lì come mostrato sopra.
Gabriel Negut,

Ho un pulsante che mi porta alla schermata di accesso e termina tutte le attività nello stack. È possibile?
Tanmay Mandal,

1

Ho trovato in questo modo, cancellerà tutta la cronologia e uscirà

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

finish();
System.exit(0);

1

Immagino di essere in ritardo, ma c'è una risposta semplice e breve. Esiste un metodo finishAffinity () in Attività che completerà l'attività corrente e tutte le attività principali, ma funziona solo in Android 4.1 o versioni successive.

Per API 16+, utilizzare

finishAffinity ();

Per meno di 16 anni, utilizzare

ActivityCompat.finishAffinity (YourActivity.this);

Spero che sia d'aiuto!

shareedit ha risposto il 27 maggio 18 alle 8:03

Akshay Taru


0

Ho trovato questa soluzione che funziona su tutti i dispositivi nonostante il livello API (anche per <11)

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);

0

Il modo migliore per chiudere tutte le attività precedenti e cancellare la memoria

finishAffinity()
System.exit(0);

0
startActivity(
                Intent(this, LoginActivity::class.java)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .addFlags(FLAG_ACTIVITY_CLEAR_TASK)
            )
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.