Android: Entfernen Sie alle vorherigen Aktivitäten vom Backstack

119

Wenn ich an zu klicken Logout in meiner Schaltfläche Profil Aktivität mag ich Benutzer nehmen Anmeldung Seite, wo er neue Anmeldeinformationen verwenden muss.

Daher habe ich diesen Code verwendet:

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

in der onButtonClickSchaltfläche Abmelden.

Das Problem ist jedoch, dass ich auf die Schaltfläche "Gerät zurück" in der Anmeldeaktivität klicke, um zur Profilaktivität zu gelangen. Ich hatte erwartet, dass die Anwendung geschlossen wird, wenn ich die Geräteschaltfläche auf LoginActivity drücke.

Was mache ich falsch?

Ich habe auch android:launchMode="singleTop"das Manifest für meine LoginActivity hinzugefügt

Danke

Archie.bpgc
quelle
@ GauravVashisth Ich habe gerade diese Lösung verfolgt stackoverflow.com/questions/5794506/…
Archie.bpgc
@ abbas.aniefa Diese Lösung habe ich etwas kompliziert. Ist das der einzige Weg, um den gesamten Backstack zu löschen? Weil ich mehr als 30 Aktivitäten habe, sollte ich diesen Broadcast-Code für alle schreiben
Archie.bpgc
Versuchen Sie dies dann unter stackoverflow.com/questions/10961481/… . Die Verwendung von Broadcast ist eine bessere Lösung.
abbas.aniefa
Ein anderer Ansatz, den Sie für die Abmeldung verwenden können: Wenn Sie abmelden, ein Flag in gemeinsam genutzten Einstellungen speichern und in jeder onRestart () -Methode einer Aktivität diesen Variablenwert überprüfen, wenn er auf true gesetzt ist, können Sie die aktuelle Aktivität beenden. Egal wie viele Aktivitäten im Hintergrund geöffnet sind. Dies würde alle Ihre Aktivitäten beenden.
Hiren Dabhi
Ihr ursprünglicher Code funktioniert tatsächlich mit einem Tweak für API Level 11 oder höher. Sie müssen nur die Flaggen in einem einzigen Anruf zusammenfügen: intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);Ich habe die Antwort von dieser Frage erhalten: stackoverflow.com/questions/3473168/…
Jokeefe

Antworten:

301

Die hier vorgeschlagene Lösung hat bei mir funktioniert:

Java

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Kotlin

val i = Intent(this, NewActivity::class.java)
// set the new task and clear flags
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(i)

Es erfordert jedoch API-Level> = 11.

kgiannakakis
quelle
FLAG_ACTIVITY_CLEAR_TASKLeute , lest die Dokumentation von. Dies ist der offizielle Weg zu bekommen. Sie müssen nicht alle Aktivitäten in der App ändern.
AlikElzin-Kilaka
Dies funktioniert nicht für Benachrichtigungen stackoverflow.com/questions/24873131/…
Sam
Ich habe meine minAPI = 16, also funktioniert das perfekt für mich. Ich habe jedoch festgestellt, dass die Ansichtsausführung mit API> 21 etwas träge und mit APIs <21 reibungslos verläuft. Hat jemand das gleiche Problem?
Red M
1
Dies wird eine neue Aufgabe für Aktivitäten erstellen
Rohit
@kgiannakakis Zweifellos funktioniert die Lösung, wenn wir nur eine Aufgabe haben (Activity Back Stack), aber wenn wir mehrere Aufgaben haben (Activity Stack), funktioniert sie nicht. Angenommen, ich habe vier Aktivitäten für meine Anwendung A, B, C und D. Angenommen, ich habe zwei Aktivitätsrückstapel A-> B-> C (Hintergrund) & D-> A-> B (Vordergrund) und If I. Rufen Sie Aktivität A von meinem aktuellen Stapel (D-> A-> B) mit Absichtsfilter auf, was Sie vorgeschlagen haben. Löschen Sie meinen aktuellen Stapel (D-> A-> B) und öffnen Sie Aktivität A, und wenn ich ihn zurückdrücke, schließen Sie ihn Anwendung, aber wenn ich die letzte App-Taste drücke, sehe ich dort zwei hintere Stapel meiner App.
Rahul Pareta
31

Hier ist eine Lösung, mit der Sie alle Aktivitäten Ihrer Anwendung löschen können, wenn Sie die Schaltfläche zum Abmelden verwenden.

Starten Sie die Aktivität jedes Mal wie folgt:

Intent myIntent = new Intent(getBaseContext(), YourNewActivity.class);
startActivityForResult(myIntent, 0);

Wenn Sie die gesamte App schließen möchten, gehen Sie folgendermaßen vor:

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALL ist eine endgültige globale Variable mit einer eindeutigen Ganzzahl, die signalisiert, dass Sie alle Aktivitäten schließen möchten.

Definieren Sie dann den onActivityResult(...)Rückruf jeder Aktivität. Wenn eine Aktivität mit dem Wert RESULT_CLOSE_ALL zurückgegeben wird, ruft sie außerdem Folgendes auf finish():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(resultCode)
    {
    case RESULT_CLOSE_ALL:
        setResult(RESULT_CLOSE_ALL);
        finish();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Dies führt zu einem Kaskadeneffekt, der alle Ihre Aktivitäten schließt.

Dies ist jedoch ein Hack und wird so verwendet startActivityForResult, dass er nicht für die Verwendung konzipiert wurde.

Ein besserer Weg, dies zu tun, wäre vielleicht die Verwendung der hier gezeigten Rundfunkempfänger:

Deaktivieren Sie beim Abmelden den Aktivitätsverlaufsstapel, um zu verhindern, dass die Schaltfläche "Zurück" nur angemeldete Aktivitäten öffnet

In diesen Threads finden Sie auch andere Methoden:

Android: Löschen Sie den Backstack

Beenden Sie alle vorherigen Aktivitäten

Anup Cowkur
quelle
4
Ist es machbar, wenn Sie ungefähr 30 Aktivitäten in der Geschichte haben?
Rakesh Gondaliya
4
sollte sein. Wenn Sie jedoch 30 Aktivitäten in der Geschichte haben, sollten Sie Ihr Design ändern. 30 scheint ein bisschen zu viel zu sein und Android könnte sie selbst umbringen.
Anup Cowkur
1
Dies scheint ein schlechter Weg zu sein. Die Antwortfrage von @RakeshGondaliya scheint legitim zu sein. 30 vielleicht nur eine Zahl, die eine "hohe" Anzahl von Aktivitäten darstellt. Diese Antwort sieht besser aus: stackoverflow.com/a/3008684/243709
Aman Alam
Diese Antwort ist großartig. Sie können die EventBus-Bibliothek auch verwenden, um Ereignisse im Backstack an Ihre Aktivitäten zu senden. github.com/greenrobot/EventBus
Stan
Verwenden Sie besser das einfache Flag 'Intent.FLAG_ACTIVITY_CLEAR_TOP' mit Absicht
Naveen Rao
18

Um den Aktivitätsstapel vollständig zu löschen, möchten Sie mit TaskStackBuilder einen neuen Aufgabenstapel erstellen, zum Beispiel:

Intent loginIntent = LoginActivity.getIntent(context);
TaskStackBuilder.create(context).addNextIntentWithParentStack(loginIntent).startActivities();

Dadurch wird nicht nur ein neuer, sauberer Aufgabenstapel erstellt, sondern es wird auch die ordnungsgemäße Funktion der Schaltfläche "Auf" ermöglicht, wenn Ihre LoginActivity über eine übergeordnete Aktivität verfügt.

Matt Accola
quelle
1
Dies ist der beste Weg, dies zu tun.
Paul Burke
FLAG_ACTIVITY_NEW_TASKoder finishAffinity()hat bei mir nicht funktioniert. Nur diese Antwort löste den Zweck.
TM
Wenn ich die App über die Zurück-Schaltfläche verlasse und über das App-Symbol zurückkehre, wird sie in der Aktivität geöffnet, die ich diese Methode aufgerufen habe. Also nicht für mich arbeiten.
Tgo1014
17

finishAffinity()in API 16 hinzugefügt. ActivityCompat.finishAffinity()In früheren Versionen verwenden. Wenn Sie eine Aktivität mit Absicht starten und die aktuelle Aktivität beenden. Verwenden Sie jetzt ActivityCompat.finishAffinity()stattdessen finish(). Alle gestapelten Aktivitäten, die unter der aktuellen Aktivität liegen, werden beendet. Es funktioniert gut für mich.

Anurag Srivastava
quelle
3
Es ist eigentlichActivityCompat.finishAffinity()
Die Berga
finishAffinity()Beendet auch die aktuelle Aktivität mit allen Aktivitäten, die im Backstack derselben Affinität vorhanden sind.
Neeraj Sewani
10

Was hat bei mir funktioniert?

Intent intent = new Intent(getApplicationContext(), HomeActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);
Mongi Zaidi
quelle
5

Eine mögliche Lösung, die ich Ihnen vorschlagen kann, ist das Hinzufügen android:launchMode="singleTop"des Manifests für meine ProfileActivity . und wenn Sie auf Abmelden klicken, können Sie sich abmelden, indem Sie erneut LoginActivity starten. Beim Abmelden können Sie dies aufrufen.

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();
Android
quelle
Ich habe dies getan, was passiert ist: Wenn ich auf die Schaltfläche "Zurück" klicke, komme ich zu Activty, von wo aus ich zu ProfileActivity
Archie.bpgc
Dies kann passieren, weil Sie zu ProfileActivity gekommen sind, indem Sie eine neue Absicht aufgerufen haben, nicht indem Sie finish () aufgerufen haben. Wie kommen Sie von anderen Aktivitäten als LoginActivty zu ProfileActivity?
Android
Ich kreuze die gleiche Frage. Ich denke, es würde nicht funktionieren, wenn die Login-Absicht vom System zerstört wurde, etwa aufgrund fehlender Memroy.
user1914692
5

Für API 11+ können Sie Folgendes verwenden Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK:

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

Alle vorherigen Aktivitäten werden vollständig gelöscht und neue Aktivitäten gestartet.

Madx
quelle
4

Sie können versuchen finishAffinity(), es schließt alle aktuellen Aktivitäten und funktioniert auf und über Android 4.1

Hase
quelle
1
finishAffinity () wurde in API 16 hinzugefügt. Verwenden Sie ActivityCompat.finishAffinity () in der vorherigen Version. Ich arbeite gut für mich.
Anurag Srivastava
2

Ich stehe auch vor dem gleichen Problem.

In der Login-Aktivität mache ich Folgendes.

    Intent myIntent = new Intent(MainActivity.this, ActivityLoggedIn.class);
    finish();
    MainActivity.this.startActivity(myIntent);  

beim Abmelden

   Intent myIntent = new Intent(ActivityLoggedIn.this, MainActivity.class);
   finish();
   ActivityLoggedIn.this.startActivity(myIntent);

Dies funktioniert gut, aber wenn ich in ActivityLoggedIn bin und die App minimiere und auf das Symbol für die Startschaltfläche in der App-Schublade klicke, startet die MainActivity erneut: - / Ich verwende das Flag

android:LaunchMode:singleTask 

für die MainActivity.

Sujal Mandal
quelle
2

Verwenden Sie Folgendes für activity

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 Verwendung von Fragmenten.

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

Aristo Michael
quelle
1

Behalte es einfach

Intent intent = new Intent(ProfileActivity.this,
    LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);
Gaurav Vashisth
quelle
4
Es funktioniert nicht. Ich kann immer noch mit dem Zurück-Button zur ProfileActivity gehen
Archie.bpgc
1

Keines der Intent-Flags hat bei mir funktioniert, aber so habe ich es behoben:

Wenn sich ein Benutzer von einer Aktivität abmeldet, musste ich eine Nachricht von dieser Aktivität senden und sie dann in den Aktivitäten empfangen, die ich schließen wollte. Danach rufe ich finish () auf. und es funktioniert ziemlich gut.

Ian Wambai
quelle
1

Versuchen Sie dies, es wird funktionieren:

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
Mohammad
quelle
1

In API - Ebene 11 oder größer ist , die Verwendung FLAG_ACTIVITY_CLEAR_TASKund die FLAG_ACTIVITY_NEW_TASKFahne Absicht , alle die Aktivität Stapel zu löschen.

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |  Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);
S.Sathya Priya
quelle
0

Benutze das

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
Wussten Sie, dass setFlags und addFlags?
GvSharma
0

Fügen Sie Manifest für Ihre Aktivität hinzu android:launchMode="singleTask"

Hally Trần
quelle
0

Fortgeschrittenes, wiederverwendbares Kotlin:

Sie können das Flag direkt mit der Setter-Methode setzen. In Kotlin orist der Ersatz für Java bitweise oder |.

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Wenn Sie dies regelmäßig verwenden möchten, erstellen Sie eine Absichtserweiterungsfunktion

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

Sie können diese Funktion dann direkt aufrufen, bevor Sie die Absicht starten

intent.clearStack()

Wenn Sie in anderen Situationen die Option zum Hinzufügen zusätzlicher Flags benötigen, fügen Sie der Erweiterungsfunktion einen optionalen Parameter hinzu.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
Gibolt
quelle