Für alle Aktivitäten in meiner Anwendung muss ein Benutzer angemeldet sein, um sie anzeigen zu können. Benutzer können sich von fast jeder Aktivität abmelden. Dies ist eine Anforderung der Anwendung. Wenn sich der Benutzer abmeldet, möchte ich den Benutzer jederzeit zum Login senden Activity
. An dieser Stelle möchte ich, dass diese Aktivität am Ende des Verlaufsstapels angezeigt wird, sodass der Benutzer durch Drücken der Schaltfläche "Zurück" zum Startbildschirm von Android zurückkehrt.
Ich habe gesehen, dass diese Frage an verschiedenen Stellen gestellt wurde, die alle mit ähnlichen Antworten beantwortet wurden (die ich hier skizziere), aber ich möchte sie hier stellen, um Feedback zu sammeln.
Ich habe versucht, die Anmeldeaktivität zu öffnen, indem ich ihre Intent
Flags gesetzt habe, FLAG_ACTIVITY_CLEAR_TOP
die wie in der Dokumentation beschrieben zu funktionieren scheinen, aber mein Ziel, die Anmeldeaktivität am unteren Rand des Verlaufsstapels zu platzieren und den Benutzer daran zu hindern, zurück zu navigieren, nicht erreicht zu zuvor gesehenen angemeldeten Aktivitäten. Ich habe auch versucht, android:launchMode="singleTop"
die Anmeldeaktivität im Manifest zu verwenden, aber dies erreicht auch nicht mein Ziel (und scheint sowieso keine Wirkung zu haben).
Ich glaube, ich muss entweder den Verlaufsstapel löschen oder alle zuvor geöffneten Aktivitäten beenden.
Eine Möglichkeit besteht darin, den Anmeldestatus jeder Aktivität zu onCreate
überprüfen und, finish()
falls nicht, angemeldet zu sein. Diese Option gefällt mir nicht, da die Schaltfläche "Zurück" weiterhin zur Verfügung steht und zurück navigiert, wenn sich die Aktivitäten schließen.
Die nächste Option besteht darin, LinkedList
Verweise auf alle offenen Aktivitäten zu verwalten, auf die von überall aus statisch zugegriffen werden kann (möglicherweise unter Verwendung schwacher Verweise). Beim Abmelden werde ich auf diese Liste zugreifen und alle zuvor geöffneten Aktivitäten durchlaufen, wobei finish()
jede aufgerufen wird. Ich werde wahrscheinlich bald mit der Implementierung dieser Methode beginnen.
Ich würde jedoch lieber einige Intent
Flaggen-Tricks anwenden, um dies zu erreichen. Ich würde mich sehr freuen zu sehen, dass ich die Anforderungen meiner Anwendung erfüllen kann, ohne eine der beiden oben beschriebenen Methoden anwenden zu müssen.
Gibt es eine Möglichkeit, dies durch Verwendung Intent
oder Manifestieren von Einstellungen zu erreichen, oder ist meine zweite Option, eine LinkedList
der geöffneten Aktivitäten beizubehalten, die beste Option? Oder gibt es eine andere Option, die ich völlig übersehen habe?
Es scheint ein Übergangsritus zu sein, dass ein neuer Android-Programmierer einen Tag damit verbringt, dieses Problem zu untersuchen und all diese StackOverflow-Threads zu lesen. Ich bin jetzt neu initiiert und hinterlasse hier Spuren meiner bescheidenen Erfahrung, um einem zukünftigen Pilger zu helfen.
Erstens gibt es nach meiner Recherche keinen offensichtlichen oder unmittelbaren Weg, dies zu tun.
(as of September 2012).
Sie würden denken, Sie könnten einfach,startActivity(new Intent(this, LoginActivity.class), CLEAR_STACK)
aber nein .Sie tun können ,
startActivity(new Intent(this, LoginActivity.class))
mitFLAG_ACTIVITY_CLEAR_TOP
- und dies wird den Rahmen veranlassen , den Stapel zu suchen nach unten, Ihre früheren ursprünglichen Instanz von LoginActivity finden, neu erstellen und löschen Sie den Rest des (nach oben) Stapel. Und da sich Login vermutlich am unteren Rand des Stapels befindet, haben Sie jetzt einen leeren Stapel und die Schaltfläche Zurück beendet nur die Anwendung.ABER - Dies funktioniert nur, wenn Sie diese ursprüngliche Instanz von LoginActivity zuvor an der Basis Ihres Stapels aktiv gelassen haben. Wenn Sie sich wie viele Programmierer dafür entschieden haben
finish()
,LoginActivity
nachdem sich der Benutzer erfolgreich angemeldet hat, befindet es sich nicht mehr auf der Basis des Stapels und dieFLAG_ACTIVITY_CLEAR_TOP
Semantik gilt nicht mehr. Am Ende erstellen Sie eine neueLoginActivity
über dem vorhandenen Stapel. Welches ist mit ziemlicher Sicherheit NICHT das, was Sie wollen (seltsames Verhalten, bei dem der Benutzer seinen Weg aus der Anmeldung in einen vorherigen Bildschirm "zurück" kann).Wenn Sie dies zuvor
finish()
getan habenLoginActivity
, müssen Sie einen Mechanismus verfolgen, um Ihren Stapel zu löschen und dann einen neuen zu startenLoginActivity
. Es scheint, dass die Antwort von@doreamon
in diesem Thread die beste Lösung ist (zumindest für mein bescheidenes Auge):https://stackoverflow.com/a/9580057/614880
Ich vermute sehr, dass die kniffligen Auswirkungen, ob Sie LoginActivity am Leben lassen, viel Verwirrung stiften.
Viel Glück.
quelle
AKTUALISIEREN
Die Super-
finishAffinity()
Methode hilft, den Code zu reduzieren, erreicht aber dasselbe. Die aktuelle Aktivität sowie alle Aktivitäten im Stapel werden beendet. VerwendengetActivity().finishAffinity()
Sie diese Option, wenn Sie sich in einem Fragment befinden.URSPRÜNGLICHE ANTWORT
Angenommen, LoginActivity -> HomeActivity -> ... -> SettingsActivity ruft signOut () auf:
HomeActivity:
Das funktioniert bei mir, hoffe, dass es auch für Sie hilfreich ist. :) :)
quelle
Wenn Sie API 11 oder höher verwenden, können Sie
FLAG_ACTIVITY_CLEAR_TASK
Folgendes versuchen: - Es scheint genau das Problem zu beheben, das Sie haben. Offensichtlich müsste die Menge vor API 11 eine Kombination aus einer zusätzlichen Überprüfung aller Aktivitäten, wie @doreamon vorschlägt, oder einem anderen Trick verwenden.(Beachten Sie auch: Um dies zu nutzen, müssen Sie übergeben
FLAG_ACTIVITY_NEW_TASK
)quelle
finish();
werde nur den Job machen, um zu verhindern, dass ich nach dem Abmelden zurückkehre. Was ist die Notwendigkeit, Flags zu setzen?Ich habe auch ein paar Stunden damit verbracht ... und bin damit einverstanden, dass FLAG_ACTIVITY_CLEAR_TOP so klingt, wie Sie es möchten: Löschen Sie den gesamten Stapel, mit Ausnahme der Aktivität, die gestartet wird, sodass die Schaltfläche Zurück die Anwendung beendet. Wie Mike Repass bereits erwähnt hat, funktioniert FLAG_ACTIVITY_CLEAR_TOP nur, wenn sich die von Ihnen gestartete Aktivität bereits im Stapel befindet. Wenn die Aktivität nicht vorhanden ist, führt die Flagge nichts aus.
Was ist zu tun? Fügen Sie die zu startende Aktivität mit FLAG_ACTIVITY_NEW_TASK in den Stapel ein. Dadurch wird diese Aktivität zum Start einer neuen Aufgabe im Verlaufsstapel. Dann fügen Sie die FLAG_ACTIVITY_CLEAR_TOP Flagge.
Wenn FLAG_ACTIVITY_CLEAR_TOP die neue Aktivität im Stapel sucht, wird sie dort angezeigt und aufgerufen, bevor alles andere gelöscht wird.
Hier ist meine Abmeldefunktion. Der Parameter Ansicht ist die Schaltfläche, an die die Funktion angehängt ist.
quelle
FLAG_ACTIVITY_CLEAR_TASK
noch nicht hinzugefügt wurdeViele Antworten. Vielleicht hilft dieser auch -
Kotlin version-
quelle
Verwenden Sie dies, es sollte für Sie hilfreich sein. Leicht modifizierte xbakesx Antwort.
quelle
Akzeptierte Lösung ist nicht korrekt, es gibt Probleme, da die Verwendung eines Rundfunkempfängers für dieses Problem keine gute Idee ist. Wenn Ihre Aktivität bereits die Methode onDestroy () aufgerufen hat, erhalten Sie keinen Empfänger. Die beste Lösung besteht darin, einen booleschen Wert für Ihre freigegebenen Einstellungen zu haben und diesen in der onCreate () -Methode Ihrer Aktivität zu überprüfen. Wenn es nicht aufgerufen werden soll, wenn der Benutzer nicht angemeldet ist, beenden Sie die Aktivität. Hier ist ein Beispielcode dafür. So einfach und funktioniert für jede Bedingung.
quelle
onResume()
Methode setzen. Denn wenn Sie die Zurück-Taste drücken, wird die Aktivität eher fortgesetzt als erstellt.Irgendwann
finish()
funktioniert es nichtIch habe dieses Problem mit gelöst
finishAffinity()
quelle
Ich würde einen anderen Ansatz für diese Frage vorschlagen. Vielleicht ist es nicht das effizienteste, aber ich denke, es ist am einfachsten anzuwenden und erfordert sehr wenig Code. Wenn Sie den nächsten Code in Ihrer ersten Aktivität schreiben (in meinem Fall Anmeldeaktivität), kann der Benutzer nach dem Abmelden nicht zu zuvor gestarteten Aktivitäten zurückkehren.
Ich gehe davon aus, dass LoginActivity unmittelbar nach der Anmeldung des Benutzers beendet ist, sodass er später nicht mehr durch Drücken der Zurück-Taste darauf zurückgreifen kann. Stattdessen muss der Benutzer eine Abmeldetaste in der App drücken, um sich ordnungsgemäß abzumelden. Was diese Abmeldeschaltfläche implementieren würde, ist eine einfache Absicht wie folgt:
Alle Vorschläge sind willkommen.
quelle
Die ausgewählte Antwort ist klug und knifflig. So habe ich es gemacht:
LoginActivity ist die Stammaktivität der Aufgabe. Setzen Sie android: noHistory = "true" in Manifest.xml; Angenommen, Sie möchten sich von SettingsActivity abmelden. Sie können dies wie folgt tun:
quelle
Hier ist die Lösung, die ich in meiner App gefunden habe.
In meiner LoginActivity starte ich nach erfolgreicher Verarbeitung eines Logins das nächste je nach API-Ebene unterschiedlich.
Dann in der onActivityForResult-Methode meiner LoginActivity:
Nach dem Verarbeiten einer Abmeldung in einer anderen Aktivität:
Wenn ich auf Lebkuchen bin, ist die LoginActivity sofort ausgeblendet, wenn ich die Zurück-Taste von MainActivity drücke. Bei Honeycomb und höher beende ich die LoginActivity erst nach der Verarbeitung eines Logins und sie wird nach der Verarbeitung eines Logins ordnungsgemäß neu erstellt.
quelle
Das hat bei mir funktioniert:
quelle
Starten Sie Ihre Aktivität mit StartActivityForResult und legen Sie während der Abmeldung Ihr Ergebnis fest und beenden Sie Ihre Aktivität entsprechend Ihrem Ergebnis
quelle
Die von @doreamon bereitgestellte Lösung funktioniert in allen Fällen einwandfrei, mit einer Ausnahme:
Wenn Nach der Anmeldung hat der Benutzer des Killing Login-Bildschirms direkt zu einem mittleren Bildschirm navigiert. Beispiel: Navigieren Sie in einem Fluss von A-> B-> C wie folgt: Anmelden -> B -> C -> Drücken Sie die Tastenkombination nach Hause. Mit FLAG_ACTIVITY_CLEAR_TOP wird nur die C-Aktivität gelöscht, da sich die Startseite (A) nicht im Stapelverlauf befindet. Durch Drücken von Zurück auf einem Bildschirm gelangen wir zurück zu B.
Um dieses Problem zu lösen, können wir einen Aktivitätsstapel (Arraylist) behalten. Wenn die Startseite gedrückt wird, müssen wir alle Aktivitäten in diesem Stapel beenden.
quelle
Dies ist durch Verwalten eines Flags in SharedPreferences oder in Application Activity möglich.
Setzen Sie beim Starten der App (auf dem Begrüßungsbildschirm) das Flag = false; Beim Abmelden Klicken Sie auf das Ereignis, setzen Sie einfach das Flag auf true und überprüfen Sie in OnResume () jeder Aktivität, ob das Flag true ist, und rufen Sie finish () auf.
Es wirkt wie ein Zauber :)
quelle
Wenn Sie auf Abmelden klicken, können Sie dies aufrufen
onActivityResult () der vorherigen Aktivität ruft diesen obigen Code erneut auf, bis Sie alle Aktivitäten abgeschlossen haben.
quelle
Sie möchten logout () und finish () für Ihre onStop () - oder onPause () -Methoden aufrufen. Dadurch wird Android gezwungen, onCreate () aufzurufen, wenn die Aktivität wieder aktiviert wird, da sie nicht mehr im Stapel ihrer Aktivität enthalten ist. Überprüfen Sie dann in onCreate () den Anmeldestatus und leiten Sie ihn an den Anmeldebildschirm weiter, wenn Sie nicht angemeldet sind.
Sie können auch den Anmeldestatus in onResume () überprüfen. Wenn Sie nicht angemeldet sind, beenden Sie () und starten Sie die Anmeldeaktivität.
quelle