Beenden Sie eine Aktivität aus einer anderen Aktivität

100

Ich möchte eine Aktivität aus einer anderen Aktivität beenden, wie zum Beispiel:

In Aktivität [A] rufe ich beim Klicken auf die Schaltfläche Aktivität [B] auf, ohne Aktivität [A] zu beenden.

In Aktivität [B] gibt es jetzt zwei Schaltflächen: Neu und Ändern . Wenn der Benutzer auf Ändern klickt, wird eine Aktivität [A] mit allen aktivierten Optionen vom Stapel genommen.

Wenn der Benutzer jedoch in Aktivität [B] auf die Schaltfläche Neu klickt , muss ich Aktivität [A] vom Stapel beenden und diese Aktivität [A] erneut in den Stapel laden.

Ich versuche es, aber ich kann Aktivität [A] nicht vom Stapel aus beenden ... Wie kann ich das tun?

Ich benutze den Code als:

Aus Aktivität [A]:

Intent GotoB = new Intent(A.this,B.class);
startActivityForResult(GotoB,1);

Eine andere Methode in der gleichen Aktivität

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

    if (requestCode == 1)
    {
        if (resultCode == 1) {
            Intent i = getIntent();
            overridePendingTransition(0, 0);
            i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();

            overridePendingTransition(0, 0);
            startActivity(i);
        }
    }
}

Klicken Sie in Aktivität [B] auf die Schaltfläche:

setResult(1);
finish();
Kanika
quelle
Hey, du wolltest eine Aktivität von einer anderen rechts beenden ... dann hatte ich die Antwort gepostet, die richtig ist. Aber warum hast du es abgelehnt?
Manjunath
Es gibt einen Thread mit ein paar netten Antworten hier: stackoverflow.com/questions/14355731/…
ab

Antworten:

188
  1. Machen Sie Ihre Aktivität A in der Manifestdatei: launchMode = "singleInstance"

  2. Wenn der Benutzer auf Neu klickt, führen Sie FirstActivity.fa.finish();die neue Absicht aus und rufen Sie sie auf.

  3. Wenn der Benutzer auf Ändern klickt, rufen Sie die neue Absicht auf oder beenden Sie einfach Aktivität B.

ERSTER WEG

Deklarieren Sie in Ihrer ersten Aktivität eine Activity objectwie folgt:

public static Activity fa;
onCreate()
{
    fa = this;
}

Verwenden Sie nun dieses Objekt in einem anderen Activity, um die erste Aktivität wie diese zu beenden.

onCreate()
{
    FirstActivity.fa.finish();
}

ZWEITER WEG

Während Sie Ihre Aktivität aufrufen, FirstActivitydie Sie beenden möchten, sobald Sie fortfahren, können Sie während des Anrufs ein Flag hinzufügenFirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Mit diesem Flag wird die Aktivität jedoch beendet, auch wenn Sie dies nicht möchten. und irgendwann, onBackwenn Sie das zeigen wollen, müssen FirstActivitySie es mit Absicht aufrufen.

MKJParekh
quelle
6
Gute Antwort..!!
Vaibhav Vajani
93
Sie haben einen statischen Verweis auf eine Aktivität. Dies wird niemals verschwinden, es sei denn, Sie löschen es manuell von irgendwoher -> Sie verursachen ein Speicherleck!
DArkO
5
Nun, es ist in Ordnung, Sie haben meine +1 für Out-of-the-Box-Denken: D, ich würde einfach zu singleTop wechseln. Es wird jedoch immer noch nicht meine erste Wahl sein, wenn ich etwas Ähnliches mache. Mit Bereinigungscode meinte ich einen Weg, die statische Referenz loszuwerden, damit kein Speicher verloren geht, aber das hängt von der App-Struktur ab.
DArkO
6
Bitte niemand benutzt die erste Lösung, es ist völlig falsch. Sie umgehen das Android-Framework auf wirklich hackige Weise, während Sie ein Zombie-Objekt erstellen. Verwenden Sie einen BroadcastReceiver.
S-K
1
Tolle Lösungen. Funktionierte sehr gut für mein Problem, bei dem ich von den Aktivitäten A-> B-> C und auf onBackPressed von C ging, ich startete eine neue Instanz von B. Aber wenn ich onBackPressed auf dieser neuen Instanz von B tat, war es früher so Gehe zur alten Instanz von B anstelle der alten Instanz von A (was ich wollte). Also folgte ich Ihrer ersten Methode in der onBackPressed von C und es gab mir das Verhalten, das ich wollte :) Vielen Dank :)
SoulRayder
87

Das können Sie tun, aber ich denke, Sie sollten den normalen Aktivitätsfluss nicht unterbrechen. Wenn Sie Ihre Aktivität beenden möchten, können Sie einfach eine Sendung von Ihrer Aktivität B an Aktivität A senden.

Erstellen Sie einen Rundfunkempfänger, bevor Sie mit Aktivität B beginnen:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context arg0, Intent intent) {
        String action = intent.getAction();
        if (action.equals("finish_activity")) {
            finish();
            // DO WHATEVER YOU WANT.
        }
    }
};
registerReceiver(broadcastReceiver, new IntentFilter("finish_activity"));

Senden Sie eine Sendung von Aktivität B an Aktivität A, wenn Sie Aktivität A von B beenden möchten

Intent intent = new Intent("finish_activity");
sendBroadcast(intent);

Ich hoffe es wird für dich funktionieren ...

Bharat Sharma
quelle
Es zeigt diesen Fehler "Syntaxfehler auf Token, stattdessen AnnotationName erwartet" auf "registerReceiver (Broadcast_Reciever, neuer IntentFilter (" finish_activity "));". Was ist los mit dir?
Behzad
2
"Sie sollten den normalen Aktivitätsfluss nicht unterbrechen" +1 dafür
S-K '18
11
Vergessen Sie nicht, sich broadcast_receiverbeiunregisterReceiver()
Jaec
Das ist die Lösung. nett
Parinda Rajapaksha
17

Dies ist eine ziemlich normale Kommunikationsfrage. Ein Ansatz wäre die Verwendung eines ResultReceivers in Aktivität A:

Intent GotoB=new Intent(A.this,B.class);
GotoB.putExtra("finisher", new ResultReceiver(null) {
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        A.this.finish();
    }
});
startActivityForResult(GotoB,1);

und dann in Aktivität B können Sie es einfach auf Anfrage wie folgt beenden:

((ResultReceiver)getIntent().getExtra("finisher")).send(1, new Bundle());

Versuchen Sie so etwas.

Femi
quelle
6
+1 just, ((ResultReceiver) getIntent (). GetParcelableExtra ("finisher")). Send (1, new Bundle ());
Hamidreza Sadegh
12

Es gibt einen Ansatz, den Sie in Ihrem Fall verwenden können.

Schritt 1: Starten Sie Aktivität B von Aktivität A.

startActivity(new Intent(A.this, B.class));

Schritt 2: Wenn der Benutzer auf die Schaltfläche Ändern klickt, starten Sie Aktivität A mit FLAG_ACTIVITY_CLEAR_TOP.Auch, übergeben Sie das Flag zusätzlich.

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "modify");
startActivity(i);
finish();

Schritt 3: Wenn der Benutzer auf die Schaltfläche Hinzufügen klickt, starten Sie Aktivität A mit FLAG_ACTIVITY_CLEAR_TOP.Auch, übergeben Sie das Flag zusätzlich. FLAG_ACTIVITY_CLEAR_TOPlöscht alle geöffneten Aktivitäten bis zum Ziel und startet neu, wenn in der Zielaktivität kein Startmodus definiert ist

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "add");
startActivity(i);
finish();

Schritt 4: Jetzt muss die onCreate()Methode der Aktivität A dieses Flag abrufen.

String flag = getIntent().getStringExtra("flag");
if(flag.equals("add")) {
    //Write a code for add
}else {
    //Write a code for modifying
}
Dharmendra
quelle
6

Beginnen Sie Ihre Aktivität mit dem Anforderungscode:

StartActivityForResult(intent,1234);

Und Sie können es von jeder anderen Aktivität wie dieser schließen:

finishActivity(1234);
Yaniv Maymon
quelle
In welcher Sprache??
Morten Holmgaard
5

Siehe meine Antwort auf die Frage zum Stapelüberlauf. Beenden Sie alle vorherigen Aktivitäten .

Was Sie brauchen, ist das Hinzufügen der Intent.FLAG_CLEAR_TOP. Dieses Flag stellt sicher, dass alle Aktivitäten über der Zielaktivität im Stapel beendet sind und dass eine angezeigt wird.

Eine andere Sache, die Sie brauchen, ist die SINGLE_TOP Flagge. Mit dieser Option verhindern Sie, dass Android eine neue Aktivität erstellt, wenn bereits eine im Stapel erstellt wurde.

Seien Sie nur vorsichtig, wenn die Aktivität bereits erstellt wurde, wird die Absicht mit diesen Flags in der aufgerufenen Methode onNewIntent(intent)(Sie müssen sie überladen, um sie zu verarbeiten) in der Zielaktivität übermittelt.

Dann onNewIntenthaben Sie eine Methode namens Neustart oder etwas, das finish()eine neue Absicht für sich selbst aufruft und startet, oder eine repopulate()Methode, die die neuen Daten festlegt. Ich bevorzuge den zweiten Ansatz, er ist kostengünstiger und Sie können die onCreateLogik jederzeit in eine separate Methode extrahieren, die Sie zum Auffüllen aufrufen können.

DArkO
quelle
4

Ich habe gerade Nepsters Lösung angewendet und funktioniert wie ein Zauber. Es gibt eine geringfügige Änderung, um es von einem Fragment auszuführen.

Zu deinem Fragment

// sending intent to onNewIntent() of MainActivity
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.putExtra("transparent_nav_changed", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Und zu Ihrem OnNewIntent () der Aktivität möchten Sie neu starten.

// recreate activity when transparent_nav was just changed
if (getIntent().getBooleanExtra("transparent_nav_changed", false)) {
    finish(); // finish and create a new Instance
    Intent restarter = new Intent(MainActivity.this, MainActivity.class);
    startActivity(restarter);
}
koras
quelle
2

Ich denke, ich habe den einfachsten Ansatz ... beim Drücken von new in B ..

Intent intent = new Intent(B.this, A.class);
intent.putExtra("NewClicked", true);
 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

und in A bekommen Sie es

  if (getIntent().getBooleanExtra("NewClicked", false)) {
        finish();// finish yourself and make a create a new Instance of yours.
      Intent intent = new Intent(A.this,A.class);
      startActivity(intent);
    }
Zar E Ahmer
quelle
1

Ich weiß, dass dies eine alte Frage ist. Einige dieser Methoden haben bei mir nicht funktioniert. Für alle, die in die Zukunft schauen oder meine Probleme haben, hat dies bei mir funktioniert

Ich habe diese Methode überschrieben onPauseund aufgerufen finish().

Tony Kutzler
quelle
-1

Erst anrufen, startactivity()dann verwendenfinish()

Dharmik Ghori
quelle