Comment redémarrer l'activité dans Android


382

Comment redémarrer un Android Activity? J'ai essayé ce qui suit, mais Activitys'arrête tout simplement.

public static void restartActivity(Activity act){

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

}

9
l'activité se termine parce que u a appelé "act.finish ();" immédiatement après avoir créé l'activité ...
Nikhil Dinesh

1
méthode obsolète
pedjjj

Réponses:


623

J'ai fait mon sélecteur de thème comme ceci:

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

Fondamentalement, j'appelle en finish()premier et j'utilise exactement la même intention avec laquelle cette activité a été lancée. Cela semble faire l'affaire?

MISE À JOUR: Comme indiqué par Ralf ci-dessous, Activity.recreate()est la voie à suivre dans l'API 11 et au-delà. C'est préférable si vous êtes dans un environnement API11 +. Vous pouvez toujours vérifier la version actuelle et appeler l'extrait de code ci-dessus si vous êtes dans l'API 10 ou inférieure. (N'oubliez pas de voter pour la réponse de Ralf!)


36
Et ça vaut le coup de voter? Ce n'était pas une exigence mentionnée par le PO. En fait, cela peut être souhaité.
EboMike

9
Eh bien, si vous n'aimez pas l'animation, vous pouvez la désactiver (comme vous l'avez démontré dans votre réponse). Cela ne rend pas ma réponse fausse en soi, cela ne montre simplement pas certaines options supplémentaires que vous êtes libre d'ajouter (et cela n'a pas été demandé dans la question).
EboMike

28
Je pense que vous vous êtes trompé. Un downvote signifie une mauvaise / mauvaise réponse, et upvote signifie qu'une réponse est excellente. La qualité d'une réponse par rapport aux autres est indiquée par le nombre de votes positifs. Je vois que vous essayez de promouvoir votre réponse, mais vous abusez du système à cette fin.
EboMike

8
+1 - cela a très bien fonctionné pour moi, et comme vous le dites, l'animation est quelque chose que je voulais, donc l'utilisateur sait qu'elle redémarre. FWIW, je me fais une règle de ne jamais voter contre les réponses des autres utilisateurs lorsque je fournis une réponse alternative à la question, bien que je vote de temps en temps lorsque ma réponse est surclassée (ne pas dire que cela s'est produit ici, juste que je le fais) .
Michael Bray

4
EboMike et Ben: Vos deux solutions ont répondu à la question du PO. Voter contre la réponse de quelqu'un uniquement pour des raisons "esthétiques" n'est pas génial. Je découragerais quiconque de le faire ici à Stackoverflow ...
ChuongPham

368

Depuis l'API niveau 11 (Honeycomb), vous pouvez appeler la méthode recreate () de l'activité (grâce à cette réponse).

La méthode recréer () agit comme un changement de configuration, donc vos méthodes onSaveInstanceState () et onRestoreInstanceState () sont également appelées, le cas échéant.


3
que faire si l'activité précédente appelait celle-ci en utilisant startActivityForResult?
développeur Android

1
Eh bien, c'est la bonne réponse si vous n'avez pas besoin de prendre en charge quelque chose de inférieur à l'API 11.
Edward Falk

@EdwardFalk y a-t-il une fonction qui le fait sur la bibliothèque de support?
développeur Android

2
Cela ne fonctionne pas dans tous les cas. Si vous avez un tiroir de navigation ouvert lors de l'appel à recréer (), il restera ouvert lors de la recréation, ce qui signifie qu'il enregistre l'état, ce qui peut ne pas être souhaitable.
Chapz

Je suis celui qui ne veut pas que l'Etat soit sauvé. Parfois, les gens veulent juste un redémarrage propre, alors ils devraient utiliser la réponse d'EboMike.
Kimi Chiu

132

Avant SDK 11, une façon de procéder est la suivante:

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

Sur HTC Desire, les animations restent (au moins lorsqu'elles sont utilisées dans la méthode onConfigurationChanged). Ils ne se produisent pas toujours, mais en utilisant le code d'EboMike, ils ne se produisent pas toujours.
Juozas Kontvainis

8
Cela ne fonctionne pas sur l'activité principale lancée par le lanceur. Votre activité finira par être cachée en raison de certains des indicateurs définis sur l'intention. Sinon ça marche bien.
Thomas Ahle

Bon point. est logique car il appelle finish () à partir de l'activité de base dans la pile.
Ben

Appeler cela pendant que nous changeons le thème de l'activité semble faire ressortir la vitesse (sans animations)
Ashok Goli

3
+1 Fonctionne bien, pour moi même avec l'activité principale. Cependant, vous devriez appeler overridePendingTransition(0, 0);après finish()et startActivity(), respectivement, pas où vous l'avez appelé ...
caw

115

Juste pour combiner les réponses de Ralf et Ben (y compris les modifications apportées dans les commentaires):

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 meilleure réponse de toutes. Croyez-le ou non, je prends toujours en charge les périphériques API 3, et la valeur VERSION.SDK_INT nécessite l'API 4. :)
Edward Falk

32

J'ai utilisé ce code afin que je puisse toujours prendre en charge les anciennes versions d'Android et l'utiliser recreate()sur les nouvelles versions d'Android.

Code:

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

Échantillon:

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

est un excellent travail pour moi !!
papo

22

Cette solution a fonctionné pour moi.

Terminez d'abord l'activité puis recommencez.

Exemple de code:

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

20

C'est de loin le moyen le plus simple de redémarrer l'activité en cours:

finish();
startActivity(getIntent());

19

Appelez cette méthode

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

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

Merci,


1
Je pense que le PO veut redémarrer n'importe quelle activité, pas seulement la première, mais cela m'a été utile.
Kristopher Johnson

1
Les deux drapeaux sont bons à savoir, mon étui semblait ne rien faire sans eux.
Owen B

1
cela a fonctionné grâce à vous! Dieu te bénisse .
Vivek

16

Même si cela a été répondu plusieurs fois.

Si vous redémarriez une activité à partir d'un fragment, je le ferais comme ceci:

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

Vous pensez peut-être que c'est un peu exagéré? Mais la Handlerpublication vous permet d'appeler cela dans une méthode de cycle de vie. Je l'ai utilisé dans onRestart/onResume méthode pour vérifier si l'état a changé entre le retour de l'utilisateur à l'application. (installé quelque chose).

Sans le Handler si vous l'appelez dans un endroit étrange, cela tuera simplement l'activité et ne la redémarrera pas.

N'hésitez pas à poser des questions.

À la vôtre, Chris


2
Excellente solution et très bon raisonnement / explication pour le gestionnaire.
JRomero

1
Pourquoi appelez-vous deux fois à "overridePendingTransition"?
développeur Android

1
@androiddeveloper Je ne me souviens pas, je pense que c'était une solution à un bug. Vous pouvez l'appeler une fois avant startActivity () et il fera comme indiqué.
Chris.Jenkins

Après avoir implémenté cela dans ma fonction onResume, le jeu s'arrête sur ma méthode onStop et a un écran noir ...
je

1
Salut chris, pouvez-vous expliquer cela un peu plus loin "Sans le gestionnaire, si vous l'appelez dans un endroit étrange, cela tuera simplement l'activité et ne la redémarrera pas." ?
parvez rafi

15

Eh bien, ce n'est pas répertorié, mais un combo de certains qui est déjà publié:

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

Cela fonctionne pour moi .. merci .. mais je veux vous demander: pourquoi quand je supprime la première partie du code (celui qui vérifie le SDK_INT) mon application fonctionne, relativement, lentement? !! .. quand je reconnecte le code, il s'exécute, relativement et évidemment, beaucoup plus vite !!!
McLan

2
Je n'en suis pas sûr. Eh bien, si vous utilisez un SDK> = 11, alors recréer () devrait être plus rapide que d'obtenir l'intention, de terminer, puis de le redémarrer. Terminez le code des appels qui s'exécute sur onStop et recréez le code des exécutions comme un changement d'orientation ... donc ce n'est pas tout à fait autant.
Codeversed

4

En conjonction avec un comportement étrange du cycle de vie de SurfaceView avec la caméra . J'ai trouvé que recréer () ne se comportait pas bien avec le cycle de vie de SurfaceViews. surfaceDestroyed n'est jamais appelé pendant le cycle de loisirs. Il est appelé après onResume (étrange), auquel cas ma SurfaceView est détruite.

La façon originale de recréer une activité fonctionne bien.

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

Je ne peux pas comprendre exactement pourquoi c'est, mais c'est juste une observation qui peut, espérons-le, guider les autres à l'avenir, car elle a résolu mes problèmes avec SurfaceViews.


4

Je me demande pourquoi personne n'a mentionné Intent.makeRestartActivityTask()qui fait proprement ce but exact.

Créez une intention qui peut être utilisée pour relancer la tâche * d'une application dans son état de base.

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

Cette méthode est définie Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASKcomme indicateurs par défaut.


3

En fait, le code suivant est valide pour les niveaux 5 et supérieurs de l'API, donc si votre API cible est inférieure à cela, vous vous retrouverez avec quelque chose de très similaire au code d'EboMike.

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

3

Il existe un moyen hacky qui devrait fonctionner sur n'importe quelle activité, y compris la principale.

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

Lorsque l'orientation change, Android recrée généralement votre activité (sauf si vous la remplacez). Cette méthode est utile pour les rotations à 180 degrés, lorsque Android ne recrée pas votre activité.


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

essayez d'utiliser cela ..


3

La solution à votre question est:

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

Vous devez effectuer un cast dans le contexte de l'activité pour démarrer une nouvelle activité et pour terminer l'activité en cours.

J'espère que cela utile .. et fonctionne pour moi.


1

Si vous supprimez la dernière ligne, vous créerez une nouvelle actactivité, mais votre ancienne instance sera toujours en vie.

Avez-vous besoin de redémarrer l'activité comme lorsque l'orientation est modifiée (c'est-à-dire que votre état est enregistré et transmis à onCreate(Bundle))?

Si vous ne le faites pas, une solution de contournement possible consisterait à utiliser une activité factice supplémentaire, qui serait démarrée à partir de la première activité, et quel travail doit en démarrer une nouvelle instance. Ou tout simplement retarder l'appel àact.finish() , une fois le nouveau lancé.

Si vous devez sauvegarder la majeure partie de l'état, vous vous retrouvez dans des eaux assez profondes, car il n'est pas trivial de transmettre toutes les propriétés de votre état, en particulier sans divulguer votre ancien contexte / activité, en le passant à la nouvelle instance.

Veuillez préciser ce que vous essayez de faire.


1
J'ai un bouton qui applique différents thèmes à l'application, une fois le thème appliqué, il est enregistré de préférence, l'activité racine redémarre, lit le thème de préférence, applique le thème dans onCreate (). Il s'avère que le code ci-dessus fonctionne correctement si l'activité n'est pas une seule instance. Je ne sais pas si c'est la meilleure pratique.

Actuellement, il n'y a pas de moyen propre et pavé de SDK pour redémarrer votre activité, AFAIK - si vous ne fuyez rien, vous pouvez être prêt à partir :)
Dimitar Dimitrov

0

C'est ainsi que je le fais.

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

-1

Si vous appelez à partir d'un fragment, faites le code ci-dessous.

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

-4

vous pouvez simplement utiliser

onRestart ()

méthode comme suit

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

et appelez onRestart () où vous souhaitez redémarrer l'activité en cours


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.