web-dev-qa-db-de.com

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

Ist es möglich, eine Aktivität auf dem Stack zu starten und die gesamte Historie vorher zu löschen?

Die Situation

Ich habe einen Aktivitätsstack, der entweder A-> B-> C oder B-> C lautet (Bildschirm A wählt das Benutzer-Token aus, aber viele Benutzer haben nur ein einzelnes Token). 

In Bildschirm C führt der Benutzer may eine Aktion aus, durch die Bildschirm B ungültig wird. Die Anwendung möchte sie also auf Bildschirm A bringen, unabhängig davon, ob er bereits im Stapel ist. 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, das genau diese Frage beantwortet. Ich habe versucht, getParent().finish() aufzurufen - dies führt immer zu einer Nullzeiger-Ausnahme. FLAG_ACTIVITY_CLEAR_TOP funktioniert nur, wenn sich die Aktivität bereits im Stapel befindet. 

288
Casebash

In der API-Ebene 11 wurde ein neues Intent Flag hinzugefügt: Intent.FLAG_ACTIVITY_CLEAR_TASK

Verwenden Sie einfach Folgendes: 

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

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

Edit: Gemäß dem Kommentar von @ Ben Pearson kann für API <= 10 jetzt die Klasse IntentCompat für dieselbe Klasse verwendet werden. Sie können das Flag IntentCompat.FLAG_ACTIVITY_CLEAR_TASK verwenden, um die Aufgabe zu löschen. So können Sie auch Pre-API-Level 11 unterstützen. 

579
Akos Cz

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

Hier ist der Aktivitätsfluss A-> B. Wenn Sie auf die Zurück-Schaltfläche von B klicken, müssen Sie die Anwendung schließen. Wenn Sie Aktivität B von A aus starten, rufen Sie einfach Finish () auf. Dadurch wird verhindert, dass Android Aktivität A in der Backstack.eg für Aktivität A speichert Loding/Splash-Bildschirm 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 die Schaltfläche "Zurück" klicken, während Sie von Aktivität D kommen. In diesem Fall sollten wir dies 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 aus dem Backstack heraus gestartet und nicht wegen einer neuen Instanz, weil Intent.FLAG_ACTIVITY_CLEAR_TOP und Intent.FLAG_ACTIVITY_NEW_TASK den Stapel löscht und zum obersten Stack wird.

43
monish george

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

Ansatz eignet sich für> = API 16.

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

Ich habe auch ein paar Stunden damit verbracht ... und stimme zu, dass FLAG_ACTIVITY_CLEAR_TOP wie gewünscht klingt: Löschen Sie den gesamten Stack, mit Ausnahme der Aktivität, die gestartet wird, sodass die Schaltfläche Zurück die Anwendung beendet. Wie Mike Repass erwähnt, funktioniert FLAG_ACTIVITY_CLEAR_TOP nur, wenn sich die Aktivität, die Sie starten, bereits im Stack befindet. Wenn die Aktivität nicht vorhanden ist, macht die Flagge nichts.

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

Wenn FLAG_ACTIVITY_CLEAR_TOP nun nach der neuen Aktivität im Stack sucht, wird diese vorhanden sein und vor dem Löschen aller anderen Objekte abgerufen.

Hier ist meine Logout-Funktion; Der View-Parameter ist die Schaltfläche, an die die Funktion 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();
}
19
user2895402

Sie sollten den Stapel nicht ändern. Die Android-Schaltfläche "Zurück" sollte wie in einem Webbrowser funktionieren.

Ich kann mir einen Weg vorstellen, es zu tun, aber es ist ein ziemlicher Hack.

  • Machen Sie Ihre Aktivitäten singleTask, indem Sie sie der AndroidManifest.__ hinzufügen. Beispiel:

    <activity Android:name=".activities.A"
              Android:label="@string/A_title"
              Android:launchMode="singleTask"/>
    
    <activity Android:name=".activities.B"
              Android:label="@string/B_title"
              Android:launchMode="singleTask"/>
    
  • Erweitere Application, die die Logik enthält, wohin sie gehen soll.

Beispiel:

public class DontHackAndroidLikeThis extends Application {

  private Stack<Activity> classes = new Stack<Activity>();

  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 bis C:

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

In C:

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

und führen Sie die Zurück-Taste vom Stack aus auf pop().

Wieder sollte man das nicht tun :)

12
Macarse

Vergewissern Sie sich unmittelbar nach dem Starten einer neuen Aktivität mit startActivity, dass Sie finish() aufrufen, damit die aktuelle Aktivität nicht hinter der neuen Aktivität liegt.

11
Keith Maurino

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

Versuchen Sie unter dem Code,

Intent intent = new Intent(ManageProfileActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK| 
                Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
0

Für mich keine der oben genannten Methoden funktioniert nicht.

Tun Sie dies einfach, um alle vorherigen Aktivitäten zu löschen :

finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)