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);
Jay Mayu
quelle
1
Überprüfen Sie diesen Link ... stackoverflow.com/questions/5139686/exit-an-android-app/…
xydev
Mögliches Duplikat von Android: Löschen Sie den Backstack
Mehdi Dehghani

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.

Cynichniy Bandera
quelle
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 .

David Olsson
quelle
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);
whlk
quelle
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

Hiren Patel
quelle
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.

Prashant Gami
quelle
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();
Sakib Syed
quelle
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.

Kevin Lee
quelle
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

maXp
quelle
2

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

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
BYISHIMO Audace
quelle
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()
Gibolt
quelle