Android: Aktivitätsstapel löschen


132

Ich habe mehrere Aktivitäten in meiner Bewerbung. und der Fluss ist sehr kompliziert. Wenn ich auf die Abmeldeanwendung klicke, navigiere ich zum Anmeldebildschirm und von dort aus kann der Benutzer über die Schaltfläche Abbrechen (Anrufen system.exit(0)) beenden.

Wenn ich die Schaltfläche "Beenden" oder "Zurück" beende, ruft das System eine Aktivität vom Stapel auf :( Wie kann ich alle Aktivitäten im Stapel löschen, wenn ich den Anmeldebildschirm erreiche? Das Aufrufen finish()ist nicht praktikabel, da es so viele Aktivitäten gibt und einige Aktivitäten nicht geschlossen werden sollten, wenn Sie sind aktiv, z. B. native Kamera, die Aktivitäten aufruft.

validateuser logoutuser = new validateuser();
logoutuser.logOut();
Intent loginscreen = new Intent(homepage.this, Login2.class);
(homepage.this).finish();
loginscreen.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(loginscreen);


Antworten:


339

Die meisten von euch liegen falsch. Wenn Sie einen vorhandenen Aktivitätsstapel schließen möchten, unabhängig davon, was sich dort befindet, und einen neuen Stamm erstellen möchten, müssen Sie folgende Flags verwenden:

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

Aus dem Dokument :

public static final int FLAG_ACTIVITY_CLEAR_TASK
Hinzugefügt in API Level 11

Wenn Context.startActivity()dieses Flag in einer übergebenen Absicht festgelegt ist , wird jede vorhandene Aufgabe, die der Aktivität zugeordnet wäre, gelöscht, bevor die Aktivität gestartet wird. Das heißt, die Aktivität wird zur neuen Wurzel einer ansonsten leeren Aufgabe, und alle alten Aktivitäten werden beendet. Dies kann nur in Verbindung mit verwendet werden FLAG_ACTIVITY_NEW_TASK.


Hat perfekt funktioniert. Vielen Dank. Seltsamerweise gab es keinen Fehler mit minSDK = 9.
Mahm00d

Ehrlich gesagt habe ich diese Funktionalität nie benutzt, nach einem Absturz wiederbelebt usw. und mich eher darauf konzentriert, die Probleme zu beheben, die den Absturz verursacht haben)
Cynichniy Bandera

Dieselbe Funktionalität bietet auch die IntentCompat.makeRestartActivityTaskSupport-Bibliothek.
Sealskej

Wenn Sie nur diese beiden Flags hinzufügen, bleibt die Aktivitätsstapelspur zurück (beginnt über der vorherigen), und dann wird Intent.FLAG_ACTIVITY_CLEAR_TOP hinzugefügt, wodurch die Anwendung einfach neu gestartet und dann vollständig beendet wird. Ich habe Aktivitäten explizit keine Flagge hinzugefügt. Was könnte das Problem sein?
Farid

1
Einer der besten Anfänge: "Die meisten von Ihnen liegen falsch."
Nibbana

31

Wenn Sie startActivitydie letzte Aktivität aufrufen, können Sie diese immer verwenden

Intent.FLAG_ACTIVITY_CLEAR_TOP

als Flagge auf diese Absicht.

Lesen Sie mehr über die Fahne hier .


das hilft auch nicht. Ich rufe nur eine Aktivität auf, die nicht mit finish () endet. :(
Jay Mayu

Ich denke, FLAG_ACTIVITY_CLEAR_TOP löscht die Aktivitäten oben. Mein Problem sind Aktivitäten auf der Unterseite :(
Jay Mayu

Ich denke, es hängt davon ab, wie der Fluss tatsächlich ist. Sie sollten hier mehr darüber lesen: developer.android.com/reference/android/content/… und developer.android.com/guide/topics/fundamentals/…
David Olsson

7
Vielen Dank, dass Sie die richtigen Ressourcen angezeigt haben. Der Fehler, den ich gemacht habe, war das Schließen der Login-Aktivität. Ich sollte es nicht schließen. Wenn die Aktivität zuerst geladen wurde. Wenn ich es also mit dem Clear_top-Flag zurückrufe, löscht die Anmeldeaktivität alle Aktivitäten oben. Da die Anmeldung die erste Entrace-Aktivität ist, werden alle danach gestarteten Aktivitäten gelöscht. so Bingo hat es funktioniert :)
Jay Mayu

13
Aus der Dokumentation geht hervor, dass FLAG_ACTIVITY_CLEAR_TOP den Stapel nur löscht, wenn die spezifische Aktivität "bereits in der aktuellen Aufgabe ausgeführt wird"
AlikElzin-kilaka

16

Hier ist eine einfache Hilfsmethode zum Starten einer neuen Aktivität als neue Top-Aktivität, die von API-Ebene 4 bis zur aktuellen Version 17 funktioniert:

static void startNewMainActivity(Activity currentActivity, Class<? extends Activity> newTopActivityClass) {
    Intent intent = new Intent(currentActivity, newTopActivityClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        intent.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK which is only available from API level 11
    currentActivity.startActivity(intent);
}

Nennen Sie es so aus Ihrer aktuellen Aktivität:

startNewMainActivity(this, MainActivity.class);

1
Könnten Sie nicht als immer nur intent.addFlags (0x8000) verwenden? und das vereinfachen?
Davor

Da dieses Flag erstmals in Honeycomb eingeführt wurde, habe ich keine Ahnung, welche Auswirkungen es auf frühere Versionen haben könnte. Das war ich also als Precaucios. Aber ich denke, die Entfernung des Zustands sollte kein Problem sein.
whlk

1
Sie möchten dieses Flag hinzufügen, wenn die API-Ebene <11 ist, dann müssen Sie es tun, Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMBsonst intent.addFlags(0x8000);wird es nie hinzugefügt
Straw Hat

Ich lasse den Benutzer viele Aktivitäten nacheinander durch Absichten ausführen. Muss ich etwas tun, um sicherzustellen, dass die App nicht mit zu vielen Aktivitäten auf dem Stapel abstürzt? Vielen Dank!
Ruchir Baronia

9

Löschen Sie den Aktivitäts-Backstate mit dem folgenden Code:

Intent intent = new Intent(Your_Current_Activity.this, Your_Destination_Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Getan


Ich lasse den Benutzer viele Aktivitäten nacheinander durch Absichten ausführen. Muss ich etwas tun, um sicherzustellen, dass die App nicht mit zu vielen Aktivitäten auf dem Stapel abstürzt? Vielen Dank!
Ruchir Baronia

@RuchirBaronia, Wenn Sie gehen A -> B -> C -> D -> E -> F -> G -> H, jetzt H -> Ich schreibe meinen Code, als ich letzte Aktivität sein werde, dann drücken Sie die Zurück-Taste Die App wird geschlossen, da die App keine Backstate-Aktivität hat. Ich hoffe, dies hilft Ihnen.
Hiren Patel

Muss ich das trotzdem tun? Was passiert, wenn ich den Aktivitätsstapel nie bereinige?
Ruchir Baronia

@RuchirBaronia, Backpress: H -> G -> F -> E -> D -> C -> B -> A
Hiren Patel

Aber manchmal wird ein weißer Bildschirm angezeigt, während neue Aktivitäten aufgerufen werden. Ho, um das zu lösen?
Sagar

4

In meinem Fall wurde LoginActivity ebenfalls geschlossen. Als Ergebnis,

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

hat nicht geholfen.

Allerdings Einstellung

Intent.FLAG_ACTIVITY_NEW_TASK

half mir.


Ich lasse den Benutzer viele Aktivitäten nacheinander durch Absichten ausführen. Muss ich etwas tun, um sicherzustellen, dass die App nicht mit zu vielen Aktivitäten auf dem Stapel abstürzt? Vielen Dank!
Ruchir Baronia

3
Intent intent = new Intent(LoginActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //It is use to finish current activity
startActivity(intent);
this.finish();

1
Warum verwenden Sie beide this.finish()und setFlags()auch, um aktuelle Aktivitäten zu löschen?
Sagar

3

Ich habe festgestellt, dass Sie nach einer Lösung gefragt haben, auf die Sie sich nicht verlassen können finish(), aber ich frage mich, ob dies dennoch hilfreich sein kann.

Ich habe verfolgt, ob ein Exit-Flag mit einer statischen Klassenvariablen ausgelöst wird, die die gesamte Lebensdauer der App überlebt. Verwenden Sie in jeder relevanten AktivitätonResume()

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

Die ExitHelper-Klasse

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

Angenommen, in mainActivity drückt ein Benutzer eine Taste, um das Programm zu beenden. Sie können dies festlegen ExitHelper.isExitFlagRaised = true;und dann finish(). Danach werden auch andere relevante Aktivitäten beendet, die automatisch wieder aufgenommen werden.


Was passiert, wenn ich den Code in MainActivity onresume () verwende und dann von der 2. Aktivität onbackpress
Mithu

3

Diese Entscheidung funktioniert gut:

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

Aber neue Aktivitäten werden lange gestartet und Sie sehen einige Zeit einen weißen Bildschirm. Wenn dies kritisch ist, verwenden Sie diese Problemumgehung:

public class BaseActivity extends AppCompatActivity {

    private static final String ACTION_FINISH = "action_finish";

    private BroadcastReceiver finisBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        registerReceiver(finisBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                finish();
            }
        }, new IntentFilter(ACTION_FINISH));
    }

    public void clearBackStack() {
        sendBroadcast(new Intent(ACTION_FINISH));
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(finisBroadcastReceiver);
        super.onDestroy();
    }
}

Wie man es benutzt:

public class ActivityA extends BaseActivity {

    // Click any button
    public void startActivityB() {
        startActivity(new Intent(this, ActivityB.class));
        clearBackStack();
    }
}

Nachteil: Alle Aktivitäten, die auf dem Stapel geschlossen werden müssen, müssen BaseActivity erweitern


2

Für Xamarin-Entwickler können Sie Folgendes verwenden:

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);

1

Kotlin verwenden:

Sie können das Flag direkt mit der Setter-Methode setzen. In Kotlin orist der Ersatz für Java bitweise oder |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Wenn Sie dies regelmäßig verwenden möchten, erstellen Sie eine Intent-Erweiterungsfunktion

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

Sie können diese Funktion dann direkt aufrufen, bevor Sie die Absicht starten

intent.clearStack()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.