374 Stimmen

Löschen Sie den gesamten Verlaufsstapel und starten Sie eine neue Aktivität auf Android

Ist es möglich, eine Aktivität auf dem Stapel zu starten und den gesamten Verlauf davor zu löschen?

Die Situation

Ich habe einen Aktivitätsstapel, der entweder A->B->C oder B->C umfasst (Bildschirm A wählt den Token des Benutzers aus, aber viele Benutzer haben nur einen einzigen Token).

In Bildschirm C kann der Benutzer Mai eine Aktion durchführen, durch die Bildschirm B ungültig wird, so dass die Anwendung sie zu Bildschirm A bringen will, unabhängig davon, ob dieser bereits auf dem Stapel liegt. Bildschirm A sollte dann das einzige Element auf dem Stapel in meiner Anwendung sein.

Anmerkungen

Es gibt noch viele andere ähnliche Fragen, aber ich habe nichts gefunden, was genau diese Frage beantwortet. Ich habe versucht, anzurufen getParent().finish() - führt dies immer zu einer Null-Zeiger-Ausnahme. FLAG_ACTIVITY_CLEAR_TOP funktioniert nur, wenn sich die Aktivität bereits auf dem Stapel befindet.

731voto

Akos Cz Punkte 12521

In der API-Stufe 11 wurde zu diesem Zweck eine neue Absichtsmarkierung hinzugefügt: Intent.FLAG_ACTIVITY_CLEAR_TASK

Nur zur Klarstellung, verwenden Sie dies:

Java

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

Kotlin

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Leider habe ich für API lvl <= 10 noch keine saubere Lösung für dieses Problem gefunden. Die "DontHackAndroidLikeThis"-Lösung ist in der Tat reine Schreiberei. Das sollten Sie nicht tun :)

Edit: Gemäß @ Ben Pearson Kommentar, für API <=10 kann man jetzt verwenden IntentCompat Klasse für dasselbe. Man kann verwenden IntentCompat.FLAG_ACTIVITY_CLEAR_TASK um die Aufgabe zu löschen. So können Sie auch vor API-Level 11 unterstützen.

55voto

monish george Punkte 781

Fall 1: Nur zwei Aktivitäten A und B:

Beim Klicken auf den Backbutton von B müssen wir die Anwendung schließen und dann beim Starten von Aktivität B von A aus einfach finish() aufrufen, was Android daran hindert, Aktivität A im Backstack zu speichern.

Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();

Fall 2: Mehr als zwei Tätigkeiten:

Wenn es einen Fluss wie A->B->C->D->B gibt und man auf die Schaltfläche "Zurück" in Aktivität B klickt, während man von Aktivität D kommt, sollten wir in diesem Fall verwenden.

Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);

Hier wird die Aktivität B vom Backstack aus gestartet und nicht als neue Instanz, weil Intent.FLAG_ACTIVITY_CLEAR_TOP und Intent.FLAG_ACTIVITY_NEW_TASK den Stack leert und ihn zum obersten macht, so dass beim Drücken der Back-Taste die gesamte Anwendung beendet wird.

54voto

karan Punkte 3279

Bei neueren Android-Versionen >= API 16 verwenden finishAffinity()

Ansatz ist für >= API 16 geeignet.

Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
  • Es ist dasselbe wie das Starten einer neuen Aktivität und das Löschen aller Stapel.
  • ODER Neustart zu MainActivity/FirstActivity.

26voto

user2895402 Punkte 261

Ich verbrachte ein paar Stunden auf diese zu ... und stimmen Sie zu, dass FLAG_ACTIVITY_CLEAR_TOP klingt wie das, was Sie wollen würde: löschen Sie den gesamten Stapel, mit Ausnahme der Aktivität gestartet wird, so dass die Schaltfläche Zurück die Anwendung beendet. Doch wie Mike Repass erwähnt, FLAG_ACTIVITY_CLEAR_TOP funktioniert nur, wenn die Aktivität, die Sie starten, ist bereits im Stapel; wenn die Aktivität nicht da ist, das Flag tut nichts.

Was ist zu tun? Legen Sie die zu startende Aktivität mit FLAG_ACTIVITY_NEW_TASK in den Stapel, wodurch diese Aktivität zum Beginn einer neuen Aufgabe auf dem Historienstapel wird. Fügen Sie dann das Kennzeichen FLAG_ACTIVITY_CLEAR_TOP hinzu.

Wenn FLAG_ACTIVITY_CLEAR_TOP nun nach der neuen Aktivität im Stapel sucht, ist sie dort und wird nach oben gezogen, bevor alles andere gelöscht wird.

Hier ist meine Logout-Funktion; der View-Parameter ist die Schaltfläche, mit der die Funktion verknüpft ist.

public void onLogoutClick(final View view) {
    Intent i = new Intent(this, Splash.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
    finish();
}

13voto

Keith Maurino Punkte 3324

Unmittelbar nach dem Start einer neuen Aktivität können Sie mit startActivity rufen Sie unbedingt an finish() damit die aktuelle Aktivität nicht hinter der neuen Aktivität gestapelt wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X