it-swarm.com.de

Wie verwenden Sie Intent.FLAG_ACTIVITY_CLEAR_TOP, um den Aktivitätsstapel zu löschen?

Ich habe mehrere Posts über die Verwendung dieses Tools gelesen, aber es muss etwas fehlen, da es bei mir nicht funktioniert. Meine Aktivität A hat im Manifest launchmode = "singleTop". Es startet die Aktivität B mit launchmode = "singleInstance". Aktivität B öffnet einen Browser und empfängt und beabsichtigt zurück, weshalb es singleInstance ist. Ich versuche, die Zurück-Schaltfläche zu überschreiben, damit der Benutzer zurück zu Aktivität A geschickt wird, und kann dann auf Zurück drücken, um die Aktivität zu verlassen, anstatt wieder zu Aktivität B zurückzukehren.

// activity B
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
 if (Android.os.Build.VERSION.SDK_INT < Android.os.Build.VERSION_CODES.Eclair
  && keyCode == KeyEvent.KEYCODE_BACK
  && event.getRepeatCount() == 0) onBackPressed();
 return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
 startActivity(new Intent(this, UI.class)
 .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
 return;
}

Nach der Rückkehr aus dem Browser lautet der Stapel ... A, B, Browser, B

Ich erwarte, dass dieser Code den Stapel auf ... A ... ändert, sodass der Benutzer durch erneutes Drücken zurück zum Startbildschirm gelangt.

Stattdessen scheint es den Stack zu ändern in ... A, B, Browser, B, A ... als ob diese Flags nicht da wären.

Ich habe versucht, finish () in Aktivität B nach startActivity aufzurufen, aber dann bringt mich der Zurück-Button wieder zurück zum Browser!

Was vermisse ich? Vielen Dank!

75
piusvelte

@bitestar hat die richtige Lösung, aber es gibt noch einen Schritt:

Es wurde in den Dokumenten versteckt, Sie müssen jedoch das launchMode des Activity in etwas anderes als standard ändern. Andernfalls wird es zerstört und neu erstellt, anstatt nach oben zurückgesetzt zu werden.

64
ScouseChris

Ich habe die Aktivität A-> B-> C-> D gestartet. Wenn die Zurück-Taste bei Aktivität DI gedrückt wird, möchten Sie zu Aktivität A gehen. Da A mein Startpunkt ist und sich daher bereits auf dem Stapel befindet, werden alle Aktivitäten auf A gelöscht, und Sie können nicht zu einer anderen Aktivität von A zurückkehren .

Das funktioniert tatsächlich in meinem Code:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent a = new Intent(this,A.class);
        a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(a);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}       
103

Dafür benutze ich FLAG_ACTIVITY_CLEAR_TOP Flag zum Starten von Intent
(ohne FLAG_ACTIVITY_NEW_TASK)

und launchMode = "singleTask" im Manifest für gestartete Aktivität.

Scheint so, als ob es funktioniert, wie ich es brauche - die Aktivität wird nicht neu gestartet und alle anderen Aktivitäten werden geschlossen.

19
Fedir Tsapana

Obwohl diese Frage bereits ausreichend beantwortet wurde, dachte ich, jemand würde wissen wollen, warum diese Flagge auf diese besondere Weise funktioniert. Dies habe ich in Android-Dokumentation gefunden

Die aktuell ausgeführte Instanz von Aktivität B im obigen Beispiel erhält entweder die neue Absicht, die Sie hier mit der Methode onNewIntent () beginnen, oder wird selbst beendet und mit der neuen Absicht neu gestartet.

Wenn der Startmodus als "mehrfach" (Standardeinstellung) deklariert wurde und Sie FLAG_ACTIVITY_SINGLE_TOP nicht in der gleichen Absicht festgelegt haben, wird er beendet und neu erstellt. Für alle anderen Startmodi oder wenn FLAG_ACTIVITY_SINGLE_TOP festgelegt ist, wird diese Absicht an die aktuelle Instanz von onNewIntent () übergeben.


Also entweder,
1 . Ändern Sie das launchMode der Aktivität A in etwas anderes als Standard (dh singleTask oder so). Dann ist Ihre Flagge FLAG_ACTIVITY_CLEAR_TOP startet die Aktivität A nicht neu.

oder,

2 . Verwenden Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP als deine Flagge. Dann wird es so funktionieren, wie Sie es wünschen.

10
Darpan

Ich benutze drei Flags, um das Problem zu lösen:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK | 
                Intent.FLAG_ACTIVITY_NEW_TASK);
3
Houssin Boulla

Ich weiß, dass es bereits eine akzeptierte Antwort gibt, aber ich verstehe nicht, wie es für das OP funktioniert, da FLAG_ACTIVITY_CLEAR_TOP in seinem speziellen Fall nicht sinnvoll ist. Dieses Flag ist nur bei Aktivitäten im gleiche Aufgabe relevant. Basierend auf seiner Beschreibung jede Aktivität hat ihre eigene Aufgabe: A, B und der Browser.

Etwas, das ihn vielleicht abschreckt, ist, dass A singleTop ist, wenn es singleTask sein sollte. Wenn A singleTop ist und B A startet, wird ein neues A erstellt, da A nicht in der Aufgabe von B ist. Aus der Dokumentation zu singleTop:

"Wenn oben in aktuelle Aufgabe bereits eine Instanz der Aktivität vorhanden ist, leitet das System die Absicht an diese Instanz weiter ..."

Da B A startet, ist die aktuelle Aufgabe die Aufgabe von B, die für eine einzelne Instanz ist und daher A nicht enthalten kann. Verwenden Sie singleTask, um dort das gewünschte Ergebnis zu erzielen, da das System dann die Aufgabe mit A findet und diese Aufgabe in den Vordergrund rückt.

Zuletzt, nachdem B A gestartet hat und der Benutzer von A zurück drückt, möchte das OP weder B noch den Browser sehen. Um dies zu erreichen, ist der Aufruf von finish () in B korrekt. Wieder wird FLAG_ACTIVITY_CLEAR_TOP die anderen Aktivitäten in A's Aufgabe nicht entfernen, da seine anderen Aktivitäten alle in verschiedenen Aufgaben sind. Das Teil, das ihm jedoch fehlte, ist, dass B auch FLAG_ACTIVITY_NO_HISTORY verwenden sollte, wenn die Absicht für den Browser ausgelöst wird. Hinweis: Wenn der Browser bereits ausgeführt wird, bevor die OP-Anwendung gestartet wurde, wird der Browser natürlich beim Zurückdrücken von A angezeigt Browser, bevor Sie die Anwendung starten.

2
Kevin

Fügen Sie Android: noHistory = "true" in die Manifestdatei ein.

<manifest >
        <activity
            Android:name="UI"
            Android:noHistory="true"/>

</manifest>
2
Ahmad Aghazadeh

ich habe activity_name.this.finish() aufgerufen, nachdem ich mit einer neuen Absicht begonnen habe, und es hat für mich funktioniert.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Aber es wird bei mir nicht funktionieren ... Ich schlage diese Lösung nicht zur Verwendung vor, aber wenn das Setzen eines Flags bei Ihnen nicht funktioniert, können Sie es versuchen. Trotzdem empfehle ich, es nicht zu verwenden

2

FLAG_ACTIVITY_NEW_TASK ist hier das Problem, das eine neue Aufgabe auslöst. Einfach entfernen und fertig.

Nun, ich empfehle Ihnen zu lesen, was jede Flagge tut, bevor Sie mit ihnen arbeiten

Lesen Sie this & Intent Flags here

1
100rabh

Anfangs hatte ich auch Probleme, FLAG_ACTIVITY_CLEAR_TOP zum Laufen zu bringen. Irgendwann habe ich es unter Verwendung des Wertes (0x04000000) zum Laufen gebracht. Es sieht also so aus, als gäbe es ein Problem mit Eclipse/Compiler. Aber leider wird die überlebende Aktivität neu gestartet, was ich nicht will. Es scheint also keine einfache Lösung zu geben.

1
ja_chu