Come riavviare Activity in Android


381

Come riavvio un Android Activity? Ho provato quanto segue, ma Activitysemplicemente si chiude.

public static void restartActivity(Activity act){

        Intent intent=new Intent();
        intent.setClass(act, act.getClass());
        act.startActivity(intent);
        act.finish();

}

9
l'attività termina perché hai chiamato "act.finish ();" subito dopo aver creato l'attività ...
Nikhil Dinesh,

1
metodo obsoleto
pedjjj

Risposte:


623

Ho fatto il mio cambio tema in questo modo:

Intent intent = getIntent();
finish();
startActivity(intent);

Fondamentalmente, sto chiamando finish() primo e sto usando lo stesso intento con cui è iniziata questa attività. Questo sembra fare il trucco?

AGGIORNAMENTO: Come sottolineato da Ralf di seguito, Activity.recreate()è la strada da percorrere in API 11 e oltre. Questo è preferibile se ti trovi in ​​un ambiente API11 +. Puoi comunque controllare la versione corrente e chiamare lo snippet di codice sopra se sei nell'API 10 o sotto. (Per favore, non dimenticare di votare la risposta di Ralf!)


36
E vale la pena effettuare il downvoting? Non era un requisito menzionato dal PO. In effetti, può essere desiderato.
EboMike,

9
Bene, se non ti piace l'animazione, puoi disattivarla (come hai dimostrato nella tua risposta). Ciò non rende la mia risposta di per sé sbagliata, non sta semplicemente mostrando alcune opzioni aggiuntive che sei libero di aggiungere (e che non è stato richiesto nella domanda).
EboMike,

28
Penso che tu abbia sbagliato. Un downvote significa risposta sbagliata / cattiva, e upvote significa che una risposta è ottima. Quanto è grande una risposta rispetto ad altri è indicato dal numero di voti. Vedo che stai cercando di promuovere la tua risposta, ma stai abusando del sistema a tale scopo.
EboMike,

8
+1: ha funzionato alla grande per me e, come dici tu, l'animazione è qualcosa che volevo, quindi l'utente sa che si riavvia. FWIW, faccio una regola per non sottovalutare le risposte degli altri utenti quando fornisco una risposta alternativa alla domanda, anche se ogni tanto faccio un voto positivo quando la mia risposta è surclassata (senza dire che è successo qui, solo che lo faccio) .
Michael Bray,

4
EboMike e Ben: entrambe le soluzioni hanno risposto alla domanda del PO. Votare la risposta di qualcuno semplicemente a causa della ragione "estetica" non è eccezionale.
Scoraggerei

368

Dal livello API 11 (Honeycomb), puoi chiamare il metodo ricreate () dell'attività (grazie a questa risposta).

Il metodo ricreate () si comporta come una modifica della configurazione, quindi vengono chiamati anche i metodi onSaveInstanceState () e onRestoreInstanceState (), se applicabile.


3
cosa succede se l'attività precedente lo chiamava usando startActivityForResult?
sviluppatore Android

1
Bene, è la risposta corretta se non hai bisogno di supportare qualcosa di inferiore all'API 11.
Edward Falk,

@EdwardFalk c'è qualche funzione che lo fa nella libreria di supporto?
sviluppatore Android

2
Questo non funziona in tutti i casi. Se hai un cassetto di navigazione aperto mentre chiami ricreate () rimarrà aperto quando ricreato, il che significa che salva lo stato, il che potrebbe non essere desiderabile.
Chapz,

Sono quello che non vuole che lo stato venga salvato. A volte le persone vogliono solo un riavvio pulito, quindi dovrebbero usare la risposta di EboMike.
Kimi Chiu,

132

Prima dell'SDK 11, un modo per farlo è il seguente:

public void reload() {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);
    startActivity(intent);
}

Su HTC Desire le animazioni rimangono (almeno se utilizzate nel metodo onConfigurationChanged). Non si verificano sempre, ma utilizzando il codice di EboMike non si verificano sempre.
Juozas Kontvainis,

8
Questo non funziona sull'attività principale avviata dal programma di avvio. La tua attività finirà nascosta a causa di alcune delle bandiere impostate sull'intento. Altrimenti funziona bene.
Thomas Ahle,

Buon punto. ha senso perché chiama finish () dall'attività di base nello stack.
Ben

Chiamare questo mentre cambiamo il tema dell'Attività sembra far emergere la velocità (senza animazioni)
Ashok Goli,

3
+1 Funziona bene, anche per me con l'attività principale. Tuttavia, dovresti chiamare overridePendingTransition(0, 0);dopo finish()e startActivity(), rispettivamente, non dove l'hai chiamato ...
caw

115

Solo per combinare le risposte di Ralf e Ben (comprese le modifiche apportate nei commenti):

if (Build.VERSION.SDK_INT >= 11) {
    recreate();
} else {
    Intent intent = getIntent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);

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

8
La migliore risposta di tutte. Che ci crediate o no, sto ancora supportando i dispositivi API 3 e il valore VERSION.SDK_INT richiede API 4. :)
Edward Falk,

31

Ho usato questo codice in modo da poter supportare versioni precedenti di Android e utilizzarle recreate()su versioni più recenti di Android.

Codice:

public static void restartActivity(Activity activity){
    if (Build.VERSION.SDK_INT >= 11) {
        activity.recreate();
    } else {
        activity.finish();
        activity.startActivity(activity.getIntent());
    }
}

Campione:

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    private Activity mActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mActivity = MainActivity.this;

        Button button = (Button) findViewById(R.id.restart_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                restartActivity(mActivity);
            }
        });
    }

    public static void restartActivity(Activity activity) {
        if (Build.VERSION.SDK_INT >= 11) {
            activity.recreate();
        } else {
            activity.finish();
            activity.startActivity(activity.getIntent());
        }
    }
}

è un ottimo lavoro per me !!
papo,

22

Questa soluzione ha funzionato per me.

Prima completa l'attività e poi riavviala.

Codice di esempio:

public void restartActivity(){
    Intent mIntent = getIntent();
    finish();
    startActivity(mIntent);
}

20

Questo è di gran lunga il modo più semplice per riavviare l'attività corrente:

finish();
startActivity(getIntent());

19

Chiama questo metodo

private void restartFirstActivity()
 {
 Intent i = getApplicationContext().getPackageManager()
 .getLaunchIntentForPackage(getApplicationContext().getPackageName() );

 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
 startActivity(i);
 }

Grazie,


1
Penso che l'OP voglia riavviare qualsiasi attività, non solo la prima, ma questo mi è stato utile.
Kristopher Johnson,

1
Le due bandiere sono buone da sapere, il mio caso sembrava non fare nulla senza di loro.
Owen B

1
ha funzionato grazie a te! Dio ti benedica .
Vivek,

16

Anche se questo è stato risposto più volte.

Se riavvio di un'attività da un frammento, lo farei così:

new Handler().post(new Runnable() {

         @Override
         public void run()
         {
            Intent intent = getActivity().getIntent();
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
            getActivity().overridePendingTransition(0, 0);
            getActivity().finish();

            getActivity().overridePendingTransition(0, 0);
            startActivity(intent);
        }
    });

Quindi potresti pensare che sia un po 'eccessivo? Ma la Handlerpubblicazione ti consente di chiamare questo in un metodo del ciclo di vita. Ho usato questo in onRestart/ onResumemetodi per verificare se lo stato è cambiato tra l'utente che torna all'app. (installato qualcosa).

Senza il Handlerse lo chiami in un posto strano, ucciderà semplicemente l'attività e non la riavvierà.

Sentiti libero di porre qualsiasi domanda.

Saluti, Chris


2
Ottima soluzione e ottimo ragionamento / spiegazione per l'handler.
JRomero,

1
Perché chiami due volte per "overridePendingTransition"?
sviluppatore Android

1
@androiddeveloper Non ricordo, penso che sia stata una soluzione a un bug. Puoi chiamarlo una volta prima di startActivity () e farà come detto.
Chris.Jenkins,

Dopo aver implementato questo nella mia funzione onResume, il gioco si ferma sul mio metodo onStop e ha una schermata nera ... non so perché
Scumble373

1
Ciao chris, puoi spiegarlo un po 'di più "Senza l'handler se lo chiami in un posto strano ucciderà semplicemente l'attività e non la riavvierà". ?
parvez rafi,

15

Bene, questo non è elencato ma una combinazione di alcuni che è già pubblicata:

if (Build.VERSION.SDK_INT >= 11) {
    recreate();   
} else {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
}

Funziona per me .. grazie .. ma voglio chiederti: perché quando rimuovo la prima parte del codice (quella che controlla SDK_INT) la mia app funziona, relativamente, lentamente? !! .. quando ricollego nuovamente il codice viene eseguito, relativamente e ovviamente, molto più velocemente !!!
McLan,

2
Non ne sono sicuro. Bene, se stai usando un SDK che è> = 11, ricreare () dovrebbe essere più veloce di ottenere l'intento, finire, quindi avviarlo di nuovo. Termina il codice delle chiamate che viene eseguito su onStop e ricrea il codice delle esecuzioni come il cambio di orientamento ... quindi non è così tanto da fare.
Codeversed

4

Insieme allo strano comportamento del ciclo di vita di SurfaceView con la videocamera . Ho scoperto che ricreate () non si comporta bene con il ciclo di vita di SurfaceViews. surfaceDestroyed non viene mai chiamato durante il ciclo di ricreazione. Si chiama dopo onResume (strano), a quel punto il mio SurfaceView viene distrutto.

Il modo originale di ricreare un'attività funziona bene.

Intent intent = getIntent();
finish();
startActivity(intent);

Non riesco a capire esattamente perché, ma è solo un'osservazione che spera possa guidare gli altri in futuro perché ha risolto i miei problemi con SurfaceViews


4

Mi chiedo perché nessuno abbia menzionato ciò Intent.makeRestartActivityTask()che fa chiaramente questo preciso scopo.

Crea un Intento che può essere utilizzato per riavviare l'attività di un'applicazione * nel suo stato di base.

startActivity(Intent.makeRestartActivityTask(getActivity().getIntent().getComponent()));

Questo metodo imposta Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASKcome flag predefiniti.


3

In realtà il seguente codice è valido per API dal 5 in su, quindi se l'API di destinazione è inferiore a questa, otterrai qualcosa di molto simile al codice di EboMike.

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
overridePendingTransition(0, 0);

3

C'è un modo confuso che dovrebbe funzionare su qualsiasi attività, compresa quella principale.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

Quando l'orientamento cambia, Android generalmente ricrea la tua attività (a meno che tu non la ignori). Questo metodo è utile per rotazioni di 180 gradi, quando Android non ricrea la tua attività.


3
public void onRestart() {
    super.onRestart();
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    finish();
    act.startActivity(intent);
}

prova ad usare questo ..


3

La soluzione per la tua domanda è:

public static void restartActivity(Activity act){
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    ((Activity)act).startActivity(intent);
    ((Activity)act).finish();
}

È necessario eseguire il cast nel contesto dell'attività per avviare una nuova attività e per terminare l'attività corrente.

Spero che questo sia utile ... e funzioni per me.


1

Se rimuovi l'ultima riga, creerai una nuova actattività, ma la tua vecchia istanza sarà ancora attiva.

Devi riavviare l'attività come quando l'orientamento viene modificato (ovvero il tuo stato viene salvato e passato a onCreate(Bundle))?

In caso contrario, una possibile soluzione alternativa consisterebbe nell'utilizzare un'attività aggiuntiva fittizia, che verrebbe avviata dalla prima attività e quale lavoro è avviare una nuova istanza di essa. O semplicemente ritardare la chiamata aact.finish() , dopo l'avvio di quello nuovo.

Se devi salvare la maggior parte dello stato, ti trovi in ​​acque abbastanza profonde, perché non è banale passare tutte le proprietà del tuo stato, soprattutto senza perdere il tuo vecchio contesto / attività, passandolo alla nuova istanza.

Per favore, specifica cosa stai cercando di fare.


1
Ho un pulsante che applica diversi temi all'app, dopo che il tema è stato applicato, viene salvato nelle preferenze, l'attività di root viene riavviata, legge il tema dalle preferenze, applica il tema in onCreate (). Si scopre che il codice sopra funziona correttamente se l'attività non è single_instance. Non sono sicuro che sia la migliore pratica.

Al momento, non esiste un modo pulito e basato sull'SDK per riavviare la tua attività, AFAIK - se non perdi nulla, potresti essere pronto per partire :)
Dimitar Dimitrov,

0

Questo è il modo in cui lo faccio.

        val i = Intent(context!!, MainActivity::class.java)
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        startActivity(i)

-1

Se stai chiamando da un frammento, procedi nel seguente modo.

Intent intent = getActivity().getIntent();
getActivity().finish();
startActivity(intent);

-4

puoi semplicemente usare

onRestart ()

metodo come segue

 @Override
    protected void onRestart() {
        super.onRestart();
        setContentView(R.layout.add_entry);
    }

e chiama onRestart () dove vuoi riavviare l'attività corrente


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.