Beenden Sie alle vorherigen Aktivitäten

368

Meine Anwendung verfügt über die folgenden Ablaufbildschirme:

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

Jetzt habe ich log out in jedem Bildschirm eine gemeinsame Schaltfläche

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

Ich möchte, dass, wenn der Benutzer auf die Schaltfläche zum Abmelden klickt (von einem beliebigen Bildschirm aus), alle Bildschirme beendet werden und ein neuer Bildschirm Log ingeöffnet wird.

Ich habe fast alle versucht FLAG_ACTIVITY, dies zu erreichen. Ich gehe auch einige Antworten im Stackoverflow durch, kann das Problem aber nicht lösen. Meine Anwendung ist auf Android 1.6, kann also nicht verwendet werdenFLAG_ACTIVITY_CLEAR_TASK

Gibt es eine Möglichkeit, das Problem zu lösen?

Tanmay Mandal
quelle
Führen Sie Ihre verschachtelten Aktivitäten mit startActivityForResult aus?
Woodshy
Alle Aktivitäten werden mit startActivity gestartet.
Tanmay Mandal
Ich verwende verschachtelte Aktivitäten, während cod finishaffinitytask () in verschachtelten Aktivitäten ausführt. ändert es das Verhalten? wie manchmal bekomme ich Fehler liefern Ergebnis ResultInfo, wenn finishaffinitytask ausgeführt wird.
Ripal Tamboli
Bitte überprüfen Sie diese Antwort, es wird Ihnen sicherlich helfen stackoverflow.com/a/25159180/2732632
Kimmi Dhingra
3
Android 21 führte Activity.finishAndRemoveTask () ein.
Joseph Johnson

Antworten:

543

Verwenden:

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

Dadurch werden alle Aktivitäten über dem Haus gelöscht.

Angenommen, Sie beenden den Anmeldebildschirm, wenn sich der Benutzer anmeldet und die Startseite erstellt wird, und anschließend alle Bildschirme von 1 bis 5 darüber. Der Code, den ich gepostet habe, bringt Sie zum Startbildschirm zurück und beendet alle anderen Aktivitäten. Sie können der Absicht ein zusätzliches hinzufügen und dies in der Startbildschirmaktivität lesen und auch beenden (möglicherweise den Anmeldebildschirm von dort aus erneut starten oder so).

Ich bin mir nicht sicher, aber Sie können auch versuchen, sich mit dieser Flagge anzumelden. Ich weiß nicht, wie die Aktivitäten in diesem Fall bestellt werden. Sie wissen also nicht, ob die Bilder unter dem Bildschirm, auf dem Sie sich befinden, einschließlich des Bildschirms, auf dem Sie sich gerade befinden, gelöscht werden, aber es ist definitiv der richtige Weg.

Hoffe das hilft.

DArkO
quelle
Der Benutzer zeigt seinen ersten Bildschirm als Startbildschirm an, das ist das Hauptproblem.
Tanmay Mandal
Nun, ich habe meine Antwort. Sie müssen zum Startbildschirm zurückkehren und diesen beenden. Daher ruft der Prozess die obige Absicht von jedem Bildschirm aus auf. Erhalten Sie die Absicht auf dem Startbildschirm und starten Sie sofort die Absicht, sich anzumelden und nach der startActivity-Methode nach Hause zu gehen. Sie können die ausstehende Animation auch für In und Out auf Null überschreiben, damit der Übergang nicht angezeigt wird (ich mache das, weil es sich etwas schneller anfühlt). Das sollte also für das, was Sie brauchen, gut funktionieren.
DArkO
10
Anstatt die Aktivität als zu deklarieren singleInstance, sollten Sie sie FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOPals Flags für die Absicht verwenden. Dadurch werden die dazwischen liegenden Aktivitäten beendet und die gewünschte Aktivität gestartet (oder wieder in den Vordergrund gebracht).
CommonsWare
13
@ CommonsWare Das Hinzufügen intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);zu meiner Aktivität hat mir nicht geholfen. Die dazwischen liegenden Aktivitäten wurden nicht beendet. Wenn ich auf dem Anmeldebildschirm zurückdrücke, werden die vorherigen Aktivitäten angezeigt. Hier ist mein Code Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);.
Tanmay Mandal
26
Dieser Code löscht nur den obersten Aktivitätsstapel, um alle Aktivitäten zu löschen. intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
Ajay Venugopal
318

Sie können es versuchen Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. Alle vorherigen Aktivitäten werden vollständig gelöscht und neue Aktivitäten gestartet.

Kong Ken
quelle
11
Die richtige Lösung, aber nur API 11+
riwnodennyk
Am Ende habe ich dieses zusätzliche Flag verwendet, da es beim Anzeigen der Hauptaktivität keine Verzögerung verursacht (es wird nicht neu gestartet, daher ist es viel schneller).
Maurizio
2
@riwnodennyk warum API 11+?
Muhammad Babar
17
Verwenden Sie IntentCompat.FLAG_ACTIVITY_CLEAR_TASK für Versionen vor 11
Steven Pena
2
@ono Ja. Das sollte alles sein, was Sie brauchen. Stellen Sie sicher, dass der Startmodus Ihrer Zielaktivität im Manifest als "singleTask" festgelegt ist.
Steven Pena
137

Fügen Sie vor dem Starten Ihrer neuen Aktivität einfach den folgenden Code hinzu:

finishAffinity();

Oder wenn Sie möchten, dass es in früheren Versionen von Android funktioniert:

ActivityCompat.finishAffinity(this);
Henrique
quelle
12
ActivityCompat.finishAffinity (this); ruft activity.finish () für api <16 auf. Es wird also nicht funktionieren.
Aamir Abro
1
@Beto Caldas, ich habe den Quellcode selbst bestätigt, er funktioniert nicht für API <16, wie AamirAbro erwähnt hat. Es wird nur die Aktivität beenden, die Sie API <16 weitergeben.
HendraWD
39

Wenn der Benutzer alle geöffneten Aktivitäten beenden möchte , sollte er eine Schaltfläche drücken, die die erste Aktivität lädt, die beim Start Ihrer Anwendung ausgeführt wird, alle anderen Aktivitäten löschen und die letzte verbleibende Aktivität beenden. Lassen Sie den folgenden Code ausführen, wenn der Benutzer die Exit-Taste drückt. In meinem Fall LoginActivityist dies die erste Aktivität in meinem Programm, die ausgeführt wird.

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

Der obige Code löscht alle Aktivitäten außer LoginActivity . Fügen Sie dann den folgenden Code in das LoginActivity's ein onCreate(...), um zu warten, wann LoginActivityneu erstellt und das' EXIT'-Signal übergeben wurde:

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

Warum ist es so schwierig, eine Exit-Schaltfläche in Android zu erstellen?

Android ist bemüht, Sie davon abzuhalten, eine Schaltfläche zum Beenden in Ihrer Anwendung zu verwenden, da der Benutzer sich nie darum kümmern soll, ob die von ihm verwendeten Programme im Hintergrund ausgeführt werden oder nicht.

Die Entwickler von Android-Betriebssystemen möchten, dass Ihr Programm ein unerwartetes Herunterfahren und Ausschalten des Telefons übersteht. Wenn der Benutzer das Programm neu startet, wird es genau dort fortgesetzt, wo es aufgehört hat. So kann der Benutzer einen Anruf erhalten, während er Ihre Anwendung verwendet, und Karten öffnen, für die Ihre Anwendung für mehr Ressourcen freigegeben werden muss.

Wenn der Benutzer Ihre Anwendung wieder aufnimmt, wird er ohne Unterbrechung genau dort fortgesetzt, wo er aufgehört hat. Diese Exit-Schaltfläche beansprucht die Stromversorgung des Aktivitätsmanagers und verursacht möglicherweise Probleme mit dem automatisch verwalteten Lebenszyklus des Android-Programms.

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

Dies funktioniert für alle Android-Versionen. Wo IntentCompatdie Klasse in der Android Support-Bibliothek hinzugefügt wurde.

Juwel
quelle
IntentCompat.FLAG_ACTIVITY_CLEAR_TASKwird nicht erkannt, verwenden Intentstatt IntentCompat.
CoolMind
30

Verwenden Sie Folgendes für Aktivitäten

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

Entfernen Sie das CLEAR_TASK-Flag für die Fragmentverwendung.

Ich hoffe, dass dies für einige Leute nützlich sein kann.

Aristo Michael
quelle
24

Ich glaube, ich bin spät dran, aber es gibt eine einfache und kurze Antwort. In Activity gibt es eine finishAffinity () -Methode, mit der die aktuelle Aktivität und alle übergeordneten Aktivitäten beendet werden. Sie funktioniert jedoch nur in Android 4.1 oder höher.

Verwenden Sie für API 16+

finishAffinity();

Für unter 16 verwenden

ActivityCompat.finishAffinity(YourActivity.this);

Ich hoffe es hilft!

Akshay Taru
quelle
21

Von developer.android.com :

public void finishAffinity ()

Hinzugefügt in API Level 16

Beenden Sie diese Aktivität sowie alle Aktivitäten direkt darunter in der aktuellen Aufgabe, die dieselbe Affinität haben. Dies wird normalerweise verwendet, wenn eine Anwendung für eine andere Aufgabe gestartet werden kann (z. B. von einer ACTION_VIEW eines Inhaltstyps, den sie versteht) und der Benutzer die Aufwärtsnavigation verwendet hat, um von der aktuellen Aufgabe zu einer eigenen Aufgabe zu wechseln. Wenn der Benutzer in diesem Fall zu anderen Aktivitäten der zweiten Anwendung navigiert ist, sollten alle diese Aktivitäten im Rahmen des Aufgabenwechsels aus der ursprünglichen Aufgabe entfernt werden.

Beachten Sie, dass Sie mit diesem Finish keine Ergebnisse für die vorherige Aktivität liefern können. Wenn Sie dies versuchen, wird eine Ausnahme ausgelöst.

gmrl
quelle
19

Nebenbei bemerkt, gut zu wissen
Diese Antwort funktioniert ( 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();

während das nicht funktioniert

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

.setFlags() Ersetzt alle vorherigen Flags und fügt währenddessen keine neuen Flags hinzu.addFlags() .

Das wird also auch funktionieren

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
John
quelle
Tolle Erklärung über den Unterschied zwischen setFlag und addFlag, danke
Pelanes
13

Wenn Ihre Anwendung mindestens SDK-Version 16 hat, können Sie finishAffinity () verwenden.

Beenden Sie diese Aktivität sowie alle Aktivitäten direkt darunter in der aktuellen Aufgabe, die dieselbe Affinität haben.

Dies ist Arbeit für mich. Im Bildschirm "Top Payment" entfernen Sie alle Backstack-Aktivitäten.

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

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

Jaydeep purohit
quelle
10

Eine Lösung, die ich dafür implementiert habe (ich glaube, ich habe sie irgendwo bei Stack Overflow gefunden, aber ich erinnere mich nicht, also danke an denjenigen, der das überhaupt getan hat):

Führen Sie bei jeder Ihrer Aktivitäten Folgendes aus:

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

Überschreiben Sie dann in Ihrer LoginActivity onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
Andy
quelle
3
Das ist normalerweise eine sehr schlechte Idee, obwohl es funktionieren kann, führt es einen Kontaktpunkt ein, der in Zukunft möglicherweise unterbrochen wird, und es wird schwierig sein, Fehler zu beheben. Ich erzähle Ihnen aus Erfahrung :)
Martin Marconcini
10

Verwenden Sie für die Abmeldeschaltfläche auf dem letzten Bildschirm der App diesen Code im Listener der Abmeldeschaltfläche, um alle geöffneten vorherigen Aktivitäten abzuschließen, und Ihr Problem ist behoben.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
Amrit
quelle
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();
Prashant Kumar
quelle
6
Warum zweimal FLAG_ACTIVITY_CLEAR_TASK ?
Choletski
1
Soweit ich weiß, ersetzt .setFlags die vorherigen Flags und fügt keine Flags hinzu. .addFlags ist das, was Sie verwenden wollten, nehme ich an? Verursacht den gesamten Code über i1.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); wird ausgelöscht
iOSAndroidWindowsMobileAppsDev
addFlags Funktioniert für mich
Jamil
1
setFlagsersetzt alle vorherigen, so dass zuletzt setFlagsnur gültig ist, vorherige ersetzt werden. Sie müssen also nicht anrufeni1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
mtrakal
8

Ich habe das gleiche Problem, das Sie verwenden können IntentCompat, wie folgt:

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

Dieser Code funktioniert für mich.

Android API 17

Adnan Abdollah Zaki
quelle
8

In meinem Fall verwende ich die finishAffinity()Funktion in der letzten Aktivität wie:

finishAffinity()
startHomeActivity()

Hoffe es wird nützlich sein.

Djek-Grif
quelle
7

anstatt finish()nur zu verwendenfinishAffinity();

Hitesh Kushwah
quelle
1
Gute Antwort, erfordert aber API 16
Akshay Taru
6

Anmelden> Start-> Bildschirm 1-> Bildschirm 2-> Bildschirm 3-> Bildschirm 4-> Bildschirm 5

auf Bildschirm 4 (oder einem anderen) ->

StartActivity (Anmelden)
mit
FLAG_ACTIVITY_CLEAR_TOP

Plamen Nikolov
quelle
2
Wenn ich die Zurück-Taste drücke, werden alle vorherigen Aktivitäten in der Reihenfolge angezeigt, in der sie waren. Diese Aktivitäten müssen geschlossen werden. Wenn Sie auf die Schaltfläche zum Abmelden klicken, befindet sich nur eine Aktivität im Stapel und dies ist die Anmeldeaktivität. Und es gibt keine Anmeldebildschirm. Benutzer startet vom Startbildschirm.
Tanmay Mandal
6

für API> = 15 bis API 23 einfache Lösung.

 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);
Kamal Bunkar
quelle
Erarbeiten Sie Ihre Antwort, damit jeder davon profitieren kann.
Shubhamoy
5

Wenn Sie startActivityForResult()in Ihren vorherigen Aktivitäten verwenden, überschreiben Sie einfach OnActivityResult()die darin enthaltene finish();Methode und rufen Sie sie in allen Aktivitäten auf. Dies erledigt den Job ...

ngesh
quelle
Nein, ich benutze startActivitynur.
Tanmay Mandal
Es wird schwierig sein, onActivityResultjede Aktivität aufrechtzuerhalten. Ich habe den Vorschlag von DArkO umgesetzt und mein Ziel erreicht und danke für die Hilfe.
Tanmay Mandal
3

Wenn der Benutzer auf die Schaltfläche zum Abmelden klickt, schreiben Sie den folgenden Code:

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

Und auch wenn Sie nach der Anmeldung eine neue Aktivität aufrufen, verwenden Sie nicht finish ().

Nikki
quelle
2

Einfach, wenn Sie den Anmeldebildschirm verlassen, nicht, wenn Sie den Anmeldebildschirm beendet haben.

Verwenden Sie diese Option dann bei allen Weiterleitungsaktivitäten zum Abmelden:

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

Es funktioniert perfekt.

Asad Rao
quelle
1

Wenn Sie sich beim Benutzer anmelden screen 1und von dort aus zu den anderen Bildschirmen wechseln, verwenden Sie

Intent intent = new Intent(this, Screen1.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Gabriel Negut
quelle
Wenn ich die Zurück-Taste drücke, werden alle vorherigen Aktivitäten in der Reihenfolge angezeigt, in der sie waren. Diese Aktivitäten müssen geschlossen werden. Wenn Sie auf die Schaltfläche zum Abmelden klicken, befindet sich nur eine Aktivität im Stapel und dies ist die Anmeldeaktivität.
Tanmay Mandal
Wenn Sie dieses Verhalten wünschen, müssen Sie onKeyDownund onBackPressed(oder onKeyDown, wenn Sie Android-Versionen <2.0 unterstützen möchten) in jeder Ihrer Aktivitäten (mit Ausnahme der Anmeldungsversion) überschreiben und startActivity(login)dort wie oben gezeigt.
Gabriel Negut
Ich habe eine Schaltfläche, die mich zum Anmeldebildschirm führt, auf dem alle Aktivitäten im Stapel abgeschlossen sind. Ist dies möglich?
Tanmay Mandal
1

Ich habe diesen Weg gefunden, es wird die gesamte Geschichte löschen und beenden

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);
Pirooz Jenabi
quelle
1

Ich glaube, ich bin spät dran, aber es gibt eine einfache und kurze Antwort. In Activity gibt es eine finishAffinity () -Methode, mit der die aktuelle Aktivität und alle übergeordneten Aktivitäten beendet werden. Sie funktioniert jedoch nur in Android 4.1 oder höher.

Verwenden Sie für API 16+

finishAffinity ();

Für unter 16 verwenden

ActivityCompat.finishAffinity (YourActivity.this);

Ich hoffe es hilft!

shareedit antwortete am 27. Mai 18 um 8:03 Uhr

Akshay Taru

Samuel Quiroz
quelle
0

Ich fand, dass diese Lösung trotz API-Level auf jedem Gerät funktioniert (sogar für <11).

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

Der beste Weg, um alle vorherigen Aktivitäten zu schließen und den Speicher zu löschen

finishAffinity()
System.exit(0);
Shivam Tripathi
quelle
0
startActivity(
                Intent(this, LoginActivity::class.java)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .addFlags(FLAG_ACTIVITY_CLEAR_TASK)
            )
Kishan Solanki
quelle