Deaktivieren Sie beim Abmelden den Aktivitätsverlaufsstapel, um zu verhindern, dass die Schaltfläche "Zurück" nur angemeldete Aktivitäten öffnet

235

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 IntentFlags gesetzt habe, FLAG_ACTIVITY_CLEAR_TOPdie 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, LinkedListVerweise 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 IntentFlaggen-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 Intentoder Manifestieren von Einstellungen zu erreichen, oder ist meine zweite Option, eine LinkedListder geöffneten Aktivitäten beizubehalten, die beste Option? Oder gibt es eine andere Option, die ich völlig übersehen habe?

Skyler
quelle

Antworten:

213

Ich kann Ihnen einen anderen Ansatz vorschlagen, der meiner Meinung nach robuster ist. Grundsätzlich müssen Sie eine Abmeldemeldung an alle Ihre Aktivitäten senden, um in einem angemeldeten Status zu bleiben. So können Sie das in all Ihren Aktivitäten verwenden sendBroadcastund installieren BroadcastReceiver. Etwas wie das:

/** on your logout method:**/
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.package.ACTION_LOGOUT");
sendBroadcast(broadcastIntent);

Der Empfänger (gesicherte Aktivität):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /**snip **/
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("com.package.ACTION_LOGOUT");
    registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("onReceive","Logout in progress");
            //At this point you should start the login activity and finish this one
            finish();
        }
    }, intentFilter);
    //** snip **//
}
Francesco Laurita
quelle
27
@Christopher, jede Aktivität registriert sich für die Sendung, wenn sie erstellt wird. Wenn es in den Hintergrund geht (dh eine neue Aktivität wird oben im Stapel angezeigt), wird onStop () aufgerufen, es können jedoch weiterhin Sendungen empfangen werden. Sie müssen nur sicherstellen, dass Sie unregisterReceiver () in onDestroy () und nicht in onStop () aufrufen.
Russell Davis
9
Funktioniert dies, wenn eine Aktivität irgendwo im Stapel vom Betriebssystem heruntergefahren wurde, um Speicher wiederherzustellen? Dh. Wird das System davon ausgehen, dass es nach dem Senden der obigen Sendung wirklich fertig ist, und wird es beim Drücken der Zurück-Taste nicht neu erstellt?
Jan Żankowski
5
Dies scheint zwar eine elegante Lösung zu sein, es ist jedoch wichtig zu beachten, dass dies nicht synchron ist.
Che Jami
34
Eine gute Lösung, aber anstatt den Broadcast-Empfänger wie im obigen Code beschrieben zu registrieren, sollten Sie einen LocalBroadcastManager.getInstance (this) .registerReceiver (...) und einen LocalBroadcastManager.getInstance (this) .unregisterReceiver (..) verwenden. . Andernfalls kann Ihre Anwendung Absichten von jeder anderen Anwendung erhalten (Sicherheitsbedenken)
Uku Loskit
5
@ Warlock Du bist richtig. Die Gefahr dieses Ansatzes besteht darin, dass eine Aktivität im Backstack vom System zerstört wird (dies kann aus verschiedenen Gründen geschehen, z. B. aufgrund des angegebenen Szenarios mit geringem Arbeitsspeicher). In diesem Fall ist die Aktivitätsinstanz nicht für den Empfang der Sendung verfügbar. Das System navigiert jedoch weiterhin durch diese Aktivität, indem es sie neu erstellt. Dies kann getestet / reproduziert werden, indem die Entwicklereinstellung "Aktivitäten nicht
Eric Schlenz
151

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))mit FLAG_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(), LoginActivitynachdem sich der Benutzer erfolgreich angemeldet hat, befindet es sich nicht mehr auf der Basis des Stapels und die FLAG_ACTIVITY_CLEAR_TOPSemantik gilt nicht mehr. Am Ende erstellen Sie eine neue LoginActivityü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 haben LoginActivity, müssen Sie einen Mechanismus verfolgen, um Ihren Stapel zu löschen und dann einen neuen zu starten LoginActivity. Es scheint, dass die Antwort von @doreamonin 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.

Mike Repass
quelle
5
Gute Antwort. Der FLAG_ACTIVITY_CLEAR_TOP-Trick, den die meisten Leute empfehlen, funktioniert einfach nicht, wenn Sie die LoginActivity abgeschlossen haben.
Konsumierer
Vielen Dank für die Antwort. Ein anderes Szenario ist wie bei einer Sitzung (z. B. fb), auch wenn wir keine Anmeldeaktivität aufrufen, sodass die Anmeldeaktivität keinen Sinn im Stapel hat. Dann ist der oben erwähnte Ansatz nutzlos.
Prashanth Debbadwar
118

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. Verwenden getActivity().finishAffinity()Sie diese Option, wenn Sie sich in einem Fragment befinden.

finishAffinity(); 
startActivity(new Intent(mActivity, LoginActivity.class));

URSPRÜNGLICHE ANTWORT

Angenommen, LoginActivity -> HomeActivity -> ... -> SettingsActivity ruft signOut () auf:

void signOut() {
    Intent intent = new Intent(this, HomeActivity.class);
    intent.putExtra("finish", true);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // To clean up all activities
    startActivity(intent);
    finish();
}

HomeActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    boolean finish = getIntent().getBooleanExtra("finish", false);
    if (finish) {
        startActivity(new Intent(mContext, LoginActivity.class));
        finish();
        return;
    }
    initializeView();
}

Das funktioniert bei mir, hoffe, dass es auch für Sie hilfreich ist. :) :)

thanhbinh84
quelle
1
Ich denke, Ihre Lösung geht davon aus, dass der Benutzer auf signOut klickt und zu nur einer Aktivität (HomeActivity) zurückkehrt. Was ist, wenn Sie 10 Aktivitäten auf dem Stapel haben?
IgorGanapolsky
11
Wenn Sie oben in HomeActivity 10 Aktivitäten haben, hilft das Flag FLAG_ACTIVITY_CLEAR_TOP dabei, alle zu bereinigen.
thanhbinh84
1
Dies kann nur funktionieren, wenn Sie beim Starten von HomeActivity Ihr OnCreate of HomeActivity erhalten. Das einfache Starten der Heimaktivität wird sie nicht unbedingt neu erstellen, es sei denn, sie wurde bereits beendet oder zerstört. Wenn HomeActivity nicht neu erstellt werden muss, wird OnCreate nicht aufgerufen und nach dem Abmelden sitzen Sie auf Ihrer Heimaktivität.
Topwik
1
Dies ist eine mögliche Lösung, bei der eine einfache (für den Benutzer) Funktion wie das Abmelden viel weniger codiert wird.
Subin Sebastian
2
Das Intent.FLAG_ACTIVITY_CLEAR_TOP-Flag hilft beim Bereinigen aller Aktivitäten, einschließlich HomeActivity. Daher wird die onCreate () -Methode aufgerufen, wenn Sie diese Aktivität erneut starten.
thanhbinh84
73

Wenn Sie API 11 oder höher verwenden, können Sie FLAG_ACTIVITY_CLEAR_TASKFolgendes 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)

Intent intent = new Intent(this, LoginActivity.class);
intent.putExtra("finish", true); // if you are checking for this in your other Activities
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | 
                Intent.FLAG_ACTIVITY_CLEAR_TASK |
                Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
xbakesx
quelle
1
Arbeiten wie ein Zauber. Vielen Dank! Während ich auf min API 14 entwickle, ist dies das einzige, was implementiert werden muss.
AndyB
1
Ich denke, wir brauchen FLAG_ACTIVITY_CLEAR_TOP nicht, wenn wir diese Lösung für LoginActivity verwenden.
Bharat Dodeja
Ich denke, ich finish();werde nur den Job machen, um zu verhindern, dass ich nach dem Abmelden zurückkehre. Was ist die Notwendigkeit, Flags zu setzen?
Pankaj
Dies erzeugt eine Ausnahme. Für den Aufruf von startActivity () außerhalb eines Aktivitätskontexts ist das Flag FLAG_ACTIVITY_NEW_TASK erforderlich
Aman
31

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.

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();
}
christinac
quelle
1
Funktioniert nicht mit API <= 10, da FLAG_ACTIVITY_CLEAR_TASKnoch nicht hinzugefügt wurde
Youans
1
@christinac Sie sprechen von FLAG_ACTIVITY_CLEAR_TOP und Ihr Code-Snippet hat FLAG_ACTIVITY_CLEAR_TASK; was ist dann gültig?
Marian Paździoch
10

Viele Antworten. Vielleicht hilft dieser auch -

Intent intent = new Intent(activity, SignInActivity.class)
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
this.finish();

Kotlin version-

Intent(this, SignInActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}.also { startActivity(it) }
finish()
Gulshan
quelle
4

Verwenden Sie dies, es sollte für Sie hilfreich sein. Leicht modifizierte xbakesx Antwort.

Intent intent = new Intent(this, LoginActivity.class);
if(Build.VERSION.SDK_INT >= 11) {
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
} else {
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
startActivity(intent);
Mohamed Ibrahim
quelle
4

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.

protected void onResume() {
  super.onResume();
  if (isAuthRequired()) {
    checkAuthStatus();
  }
}

private void checkAuthStatus() {
  //check your shared pref value for login in this method
  if (checkIfSharedPrefLoginValueIsTrue()) {
    finish();
  }
}

boolean isAuthRequired() {
  return true;
}
Yekmer Simsek
quelle
1
Es ist Jahre her, aber ich glaube, ich habe beides getan. Jede Aktivität erweiterte LoggedInActivity, wodurch der Anmeldestatus des Benutzers in onCreate () überprüft wurde. LoggedInActivity hat auch auf die Sendung "Benutzer abgemeldet" gewartet und alles getan, um darauf zu reagieren.
Skyler
2
Wahrscheinlicher ist es, dass Sie den checkAuthStatus in die onResume()Methode setzen. Denn wenn Sie die Zurück-Taste drücken, wird die Aktivität eher fortgesetzt als erstellt.
Mai
1
@maysi Danke für den Vorschlag, ja, dieser Zurück-Button funktioniert auch richtig. Ich habe den Eintrag aktualisiert
Yekmer Simsek
3

Irgendwann finish()funktioniert es nicht

Ich habe dieses Problem mit gelöst

finishAffinity()

AJay
quelle
3

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.

@Override
public void onBackPressed() {
    // disable going back to the MainActivity
    moveTaskToBack(true);
}

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:

Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();

Alle Vorschläge sind willkommen.

Null
quelle
2

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:

    Intent i = new Intent(SettingsActivity.this, LoginActivity.class);
    i.addFlags(IntentCompat.FLAG_ACTIVITY_CLEAR_TASK
            | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(i);
t-gao
quelle
2

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.

Intent i = new Intent(this, MainActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    startActivity(i);
    finish();
} else {
    startActivityForResult(i, REQUEST_LOGIN_GINGERBREAD);
}

Dann in der onActivityForResult-Methode meiner LoginActivity:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB &&
        requestCode == REQUEST_LOGIN_GINGERBREAD &&
        resultCode == Activity.RESULT_CANCELED) {
    moveTaskToBack(true);
}

Nach dem Verarbeiten einer Abmeldung in einer anderen Aktivität:

Intent i = new Intent(this, LoginActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

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.

Seeland
quelle
Es funktioniert nicht für mich. In meinem Fall habe ich Fragmentaktivität verwendet. Die Onactivityresult-Methode wird nicht aufgerufen.
Mohamed Ibrahim
1

Das hat bei mir funktioniert:

     // After logout redirect user to Loing Activity
    Intent i = new Intent(_context, MainActivity.class);
    // Closing all the Activities
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

    // Add new Flag to start new Activity
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    // Staring Login Activity
    _context.startActivity(i);
Preetansh
quelle
Könnten Sie bitte Ihre Antwort näher erläutern und etwas mehr Beschreibung der von Ihnen bereitgestellten Lösung hinzufügen?
Abarisone
0

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

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivityForResult(intent, BACK_SCREEN);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case BACK_SCREEN:
        if (resultCode == REFRESH) {
            setResult(REFRESH);
            finish();
        }
        break;
    }
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        AlertDialog alertDialog = builder.create();

        alertDialog
                .setTitle((String) getResources().getText(R.string.home));
        alertDialog.setMessage((String) getResources().getText(
                R.string.gotoHome));
        alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                            int whichButton) {

                        setResult(REFRESH);
                        finish();
                    }

                });

        alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "No",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                            int whichButton) {
                    }
                });
        alertDialog.show();
        return true;
    } else
        return super.onKeyDown(keyCode, event);

}
Eby
quelle
0

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.

Surendra Kumar
quelle
0

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 :)

MrDumb
quelle
0

Wenn Sie auf Abmelden klicken, können Sie dies aufrufen

private void GoToPreviousActivity() {
    setResult(REQUEST_CODE_LOGOUT);
    this.finish();
}

onActivityResult () der vorherigen Aktivität ruft diesen obigen Code erneut auf, bis Sie alle Aktivitäten abgeschlossen haben.

Mak
quelle
1
Das heißt, es muss alle Aktivitäten linear durchlaufen, anstatt das Ziel () auf einmal zu senden?
IgorGanapolsky
@Igor G. Ja, es ist die alternative Möglichkeit, nacheinander fertig zu werden
Mak
-1

Eine Möglichkeit besteht darin, dass der onCreate-Status jeder Aktivität den Anmeldestatus überprüft und finish () beendet, wenn er nicht angemeldet ist. 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.

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.

Ricardo Villamil
quelle
Ich möchte mich nicht bei jeder Aktivitätspause abmelden oder anhalten. Außerdem initiiert die Anwendung das Abmelden oder Anmelden, sodass ich nicht wirklich prüfen muss, ob ich angemeldet bin.
Skyler
@ Ricardo: Benötigt Ihre Lösung keinen BroadcastReceiver?
IgorGanapolsky