Termina un'attività da un'altra attività


101

Voglio terminare un'attività da un'altra attività, come:

Nell'attività [A], al clic del pulsante, chiamo l'attività [B] senza terminare l'attività [A].

Ora nell'attività [B] ci sono due pulsanti, Nuovo e Modifica . Quando l'utente fa clic su Modifica, visualizza un'attività [A] dalla pila con tutte le opzioni selezionate.

Ma quando l'utente fa clic sul pulsante Nuovo dall'attività [B], dovrò terminare l'attività [A] dallo stack e ricaricare nuovamente quell'attività [A] nello stack.

Lo sto provando, ma non riesco a terminare l'attività [A] dallo stack ... Come posso farlo?

Sto usando il codice come:

Dall'attività [A]:

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

Un altro metodo nella stessa attività

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);
        }
    }
}

E nell'attività [B], al clic del pulsante:

setResult(1);
finish();

hey, volevi finire un'attività da un'altra a destra ... poi avevo pubblicato la risposta che è corretta. Ma perché l'hai votato?
Manjunath

C'è un thread con alcune belle risposte qui: stackoverflow.com/questions/14355731/…
ab

Risposte:


189
  1. Rendi la tua attività A nel file manifest: launchMode = "singleInstance"

  2. Quando l'utente fa clic su nuovo, esegui FirstActivity.fa.finish();e chiama il nuovo intento.

  3. Quando l'utente fa clic su Modifica, chiama il nuovo Intent o termina semplicemente l'attività B.

PRIMO MODO

Nella tua prima attività, dichiarane una Activity objectcome questa,

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

ora usa quell'oggetto in un altro Activityper finire la prima attività come questa,

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

SECONDO MODO

Mentre chiami la tua attività FirstActivityche desideri terminare non appena vai avanti, puoi aggiungere flag durante la chiamataFirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Ma usando questo flag l'attività verrà terminata anche se non lo desideri. e qualche volta onBackse vuoi mostrare lo FirstActivitydovrai chiamarlo usando l'intento.


6
Bella risposta..!!
Vaibhav Vajani

93
Stai tenendo un riferimento statico a un'attività. Questo non andrà mai via a meno che tu non lo cancelli manualmente da qualche parte -> stai creando una perdita di memoria!
DArkO

5
Bene, va bene, hai il mio +1 per pensare fuori dagli schemi: D, vorrei solo passare a singleTop. tuttavia non sarà ancora la mia prima scelta quando faccio qualcosa di simile. per codice di pulizia intendevo un modo per sbarazzarsi del riferimento statico in modo che non ci siano perdite di memoria, ma questo dipende dalla struttura dell'app.
DArkO

6
Per favore, nessuno usa la prima soluzione, è completamente sbagliata. Stai aggirando il framework Android in un modo davvero hacker mentre crei un oggetto zombi. Usa un BroadcastReceiver.
S-K

1
Soluzioni fantastiche. Ha funzionato molto bene per il mio problema in cui stavo andando dalle attività A-> B-> C e su onBackPressed di C, stavo lanciando una nuova istanza di B. Ma poi se facevo onBackPressed su quella nuova istanza di B, era solito vai alla vecchia istanza di B invece della vecchia istanza di A (quello che volevo). Quindi ho seguito il tuo primo metodo in onBackPressed di C, e mi ha dato il comportamento che volevo :) Grazie
mille

87

Puoi farlo, ma penso che non dovresti interrompere il normale flusso di attività. Se vuoi terminare la tua attività, puoi semplicemente inviare una trasmissione dalla tua attività B all'attività A.

Crea un ricevitore di trasmissione prima di iniziare l'attività B:

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"));

Invia la trasmissione dall'attività B all'attività A quando desideri terminare l'attività A da B

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

Spero che funzioni per te ...


Mostra questo errore "Errore di sintassi sui token, AnnotationName previsto invece" su "registerReceiver (broadcast_reciever, new IntentFilter (" finish_activity "));". Cosa c'è che non va?
Behzad

2
"non dovresti interrompere il normale flusso di attività" +1 per questo
S-K

11
Non dimenticare di broadcast_receiverunregisterReceiver()
annullare la


Questa è la soluzione. bello
Parinda Rajapaksha

17

Questa è una domanda di comunicazione abbastanza standard. Un approccio potrebbe essere quello di utilizzare un ResultReceiver nell'attività 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);

e poi nell'attività B puoi semplicemente finirlo su richiesta in questo modo:

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

Prova qualcosa del genere.


6
+1 solo, ((ResultReceiver) getIntent (). GetParcelableExtra ("finisher")). Send (1, new Bundle ());
Hamidreza Sadegh

12

C'è un approccio che puoi usare nel tuo caso.

Passaggio 1: avviare l'attività B dall'attività A

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

Passaggio 2: se l'utente fa clic sul pulsante di modifica, avvia l'attività A utilizzando il FLAG_ACTIVITY_CLEAR_TOP.Inoltre, passa il flag in più.

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

Passaggio 3: se l'utente fa clic sul pulsante Aggiungi, avvia l'attività A utilizzando il FLAG_ACTIVITY_CLEAR_TOP. Inoltre, passa il flag in più. FLAG_ACTIVITY_CLEAR_TOPcancellerà tutte le attività aperte fino al target e si riavvierà se nessuna modalità di avvio è definita nell'attività target

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

Passaggio 4: ora il onCreate()metodo dell'attività A, è necessario recuperare quel flag.

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

6

Inizia la tua attività con il codice di richiesta:

StartActivityForResult(intent,1234);

E puoi chiuderlo da qualsiasi altra attività come questa:

finishActivity(1234);

In che lingua ??
Morten Holmgaard

5

Vedi la mia risposta alla domanda di Stack Overflow Fine tutte le attività precedenti .

Quello che ti serve è aggiungere il file Intent.FLAG_CLEAR_TOP. Questo flag assicura che tutte le attività sopra l'attività di destinazione nello stack siano terminate e che venga visualizzata.

Un'altra cosa di cui hai bisogno è la SINGLE_TOPbandiera. Con questo impedisci ad Android di creare una nuova attività se ce n'è una già creata nello stack.

Fai solo attenzione che se l'attività è già stata creata, l'intento con questi flag verrà consegnato nel metodo chiamato onNewIntent(intent)(devi sovraccaricarlo per gestirlo) nell'attività di destinazione.

Poi, nel onNewIntentsi dispone di un metodo chiamato riavvio o qualcosa che chiamerà finish()e lanciare un nuovo intento verso se stesso, o di avere un repopulate()metodo che fisserà i nuovi dati. Preferisco il secondo approccio, è meno costoso e puoi sempre estrarre la onCreatelogica in un metodo separato che puoi chiamare per popolare.


4

Ho appena applicato la soluzione di Nepster e funziona a meraviglia. C'è una piccola modifica per eseguirlo da un frammento.

Al tuo frammento

// 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);

E al tuo OnNewIntent () dell'attività che desideri riavviare.

// 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);
}

2

Penso di avere l'approccio più semplice ... premendo nuovo in B ..

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

e in A ottenerlo

  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);
    }

1

So che questa è una vecchia domanda, alcuni di questi metodi non hanno funzionato per me, quindi per chiunque cerchi nel futuro o abbia i miei problemi questo ha funzionato per me

Ho sovrascritto onPausee chiamato finish()all'interno di quel metodo.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.