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 geht (Bildschirm A wählt das Benutzer-Token, aber viele Benutzer haben nur ein einziges Token).

In Bildschirm C kann der Benutzer eine Aktion ausführen, die Bildschirm B ungültig macht, so dass die Anwendung sie zu Bildschirm A bringen möchte, unabhängig davon, ob sie sich bereits im Stapel befindet. Bildschirm A sollte dann das einzige Element auf dem Stapel in meiner Anwendung sein.

Anmerkungen

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

Solutions Collecting From Web of "Löschen Sie den gesamten Verlaufsstapel und starten Sie eine neue Aktivität auf Android"

In API-Ebene 11 wurde nur für diesen Zweck ein neues Intent Flag hinzugefügt: Intent.FLAG_ACTIVITY_CLEAR_TASK

Nur um dies zu verdeutlichen, benutze dies:

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

Leider habe ich für API lvl < = 10 noch keine saubere Lösung gefunden. Die "DontHackAndroidLikeThis" -Lösung ist in der Tat reiner Hacker. Das solltest du nicht tun. :)

Edit: Nach @ Ben Pearson ‘s Kommentar, für API < = 10 kann man jetzt die IntentCompat Klasse für dasselbe verwenden. IntentCompat.FLAG_ACTIVITY_CLEAR_TASK Flag IntentCompat.FLAG_ACTIVITY_CLEAR_TASK kann die Aufgabe IntentCompat.FLAG_ACTIVITY_CLEAR_TASK . So können Sie auch Pre-API Level 11 unterstützen.

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

Hier ist der Aktivitätsfluss A-> B. Beim Klicken auf den Zurück-Knopf von B müssen wir die Anwendung schließen, während wir Aktivität B von A starten, nur call finish () dies verhindert, dass android Aktivität A in den Backstack.eg für Aktivität A speichert Logging / Begrüßungsbildschirm der Anwendung.

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

Fall 2: Mehr als zwei Aktivitäten:

Wenn es einen Fluss wie A-> B-> C-> D-> B gibt und wenn Sie in Aktivität B auf Zurück klicken, während Sie von Aktivität D kommen. In diesem Fall sollten wir 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 Aktivität B aus dem Backstack statt einer neuen Instanz gestartet, weil Intent.FLAG_ACTIVITY_CLEAR_TOP und Intent.FLAG_ACTIVITY_NEW_TASK den Stack löscht und zum obersten macht. Wenn wir dann die Taste drücken, wird die gesamte Anwendung beendet.

Mit der neueren Version von Android> = API 16 verwende finishAffinity()

Ansatz ist geeignet für> = API 16.

 Intent mIntent = new Intent(mContext,MainActivity.class); finishAffinity(); startActivity(mIntent); 
  • Es ist dasselbe wie das Starten neuer Aktivitäten und das Löschen aller Stapel.
  • ODER Starten Sie MainActivity / FirstActivity neu.

Ich habe auch ein paar Stunden damit verbracht … und stimme zu, dass FLAG_ACTIVITY_CLEAR_TOP wie das klingt, was Sie wollen: Löschen Sie den gesamten Stack, abgesehen von der gestarteten Aktivität, so dass die Zurück-Schaltfläche die Anwendung beendet. Wie Mike Repass bereits erwähnt hat, funktioniert FLAG_ACTIVITY_CLEAR_TOP nur, wenn die Aktivität, die Sie starten, bereits im Stapel ist. Wenn die Aktivität nicht da ist, tut die Flagge nichts.

Was ist zu tun? Legen Sie die startende Aktivität mit FLAG_ACTIVITY_NEW_TASK im Stapel ab, wodurch diese Aktivität zum Beginn einer neuen Aufgabe im Verlaufsstapel wird. Fügen Sie dann das Flag FLAG_ACTIVITY_CLEAR_TOP hinzu.

Jetzt, wenn FLAG_ACTIVITY_CLEAR_TOP die neue Aktivität im Stapel findet, wird sie da sein und hochgezogen werden, bevor alles andere gelöscht wird.

Hier ist meine Abmeldefunktion; Der View-Parameter ist die Schaltfläche, an die die function angehängt 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(); } 

Sie sollten den Stapel nicht ändern. Android Back-Taste sollte wie in einem Webbrowser funktionieren.

Ich kann mir einen Weg vorstellen, aber es ist ein harter Schlag.

  • Machen Sie Ihre Aktivitäten singleTask indem Sie sie zum AndroidManifest Beispiel:

       
  • Erweitern Sie die Application die die Logik von wo zu gehen hält.

Beispiel:

 public class DontHackAndroidLikeThis extends Application { private Stack classes = new Stack(); public Activity getBackActivity() { return classes.pop(); } public void addBackActivity(Activity activity) { classes.push(activity); } } 

Von A nach B:

 DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication(); app.addBackActivity(A.class); startActivity(this, B.class); 

Von B nach C:

 DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication(); app.addBackActivity(B.class); startActivity(this, C.class); 

In C:

 If ( shouldNotGoBackToB() ) { DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication(); app.pop(); } 

und handle mit der Zurück-Taste, um vom Stapel zu pop() .

Noch einmal, du solltest das nicht tun 🙂

startActivity Sie unmittelbar nach dem Start einer neuen Aktivität mithilfe von startActivity sicher, dass Sie finish() aufrufen finish() damit die aktuelle Aktivität nicht hinter der neuen Aktivität gestapelt wird.

Versuche dies:

 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(); 
 Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(i); 

Ich habe einen zu einfachen Hack gefunden, fügen Sie einfach ein neues Element in AndroidManifest :

  

Der android:noHistory Ihre unerwünschten Aktivitäten von Stack.

Manchmal kann Ihr Android-Emulator das eclipse-DDMS-Tool nicht verbinden und nach dem manuellen Start von adb fragen. In diesem Fall können Sie das Adb über die Eingabeaufforderung starten oder stoppen.