430

How do I restart an Android Activity? I tried the following, but the Activity simply quits.

public static void restartActivity(Activity act){

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

}
Samet ÖZTOPRAK
  • 3,112
  • 3
  • 32
  • 33

23 Answers23

680

I did my theme switcher like this:

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

Basically, I'm calling finish() first, and I'm using the exact same intent this activity was started with. That seems to do the trick?

UPDATE: As pointed out by Ralf below, Activity.recreate() is the way to go in API 11 and beyond. This is preferable if you're in an API11+ environment. You can still check the current version and call the code snippet above if you're in API 10 or below. (Please don't forget to upvote Ralf's answer!)

EboMike
  • 76,846
  • 14
  • 164
  • 167
  • 1
    the problem w/ this approach is that it animates the activity so it appears to slide in and out... – Ben May 11 '11 at 21:59
  • 9
    Well, if you don't like the animation, you can turn it off (as you demonstrated in your answer). That doesn't make my answer wrong per se, it's just not showing some additional options that you are free to add (and that wasn't asked for in the question). – EboMike May 11 '11 at 23:16
  • 3
    i never said you'r answer was wrong, a down vote doesn't necessarily mean wrong, its just not as good as another. not trying to toot my own horn here, just saying that not showing the animation gives a truer "refresh" experience from a UX perspective. – Ben May 12 '11 at 16:40
  • 31
    I think you got that wrong. A downvote means wrong/bad answer, and upvote means an answer is great. How great an answer is compared to others is indicated by the number of upvotes. I can see that you're trying to promote your answer, but you're misusing the system for that purpose. – EboMike May 12 '11 at 16:44
  • 2
    well i dont want to go on arguing this with you, lets agree to disagree. i think the voting provides a way to rank answers, you dont. we'll leave it at that. you're answer actually is decent, it just looks weird because of the animation flying in and out, I can't imagine any scenario where I'd want to have that effect. it looks like you're leaving the page, and then coming right back to it. – Ben May 12 '11 at 18:05
  • 9
    +1 - this worked great for me, and as you say, the animation is something i did want, so the user knows it is restarting. FWIW, I make it a rule never to down-vote other users answers when I provide an alternate answer to the question, although I do occasionally up-vote when my answer is outclassed (not saying that happened here, just that I do it). – Michael Bray Oct 03 '11 at 21:49
  • 5
    EboMike and Ben: Both of your solutions answered the OP's question. To vote down someone's answer purely because of "aesthetic" reason is, well, not great. I would discourage anyone from doing it here at Stackoverflow... – ChuongPham Aug 08 '13 at 14:27
  • 2
    what if the previous activity called this one using startActivityForResult ? – android developer Aug 14 '13 at 13:54
  • sometimes (on Android 6.1) it gives `java.lang.SecurityException: Not allowed to start activity Intent` – Choletski Oct 31 '16 at 07:35
  • based on experiment the difference is `recreate` will call onDestroy before starting new activity. manually starting the activity and finishing the current one does not. you must make sure every thing is closed before starting new activity manually. – M.kazem Akhgary Dec 11 '18 at 21:26
399

Since API level 11 (Honeycomb), you can call the recreate() method of the activity (thanks to this answer).

The recreate() method acts just like a configuration change, so your onSaveInstanceState() and onRestoreInstanceState() methods are also called, if applicable.

Community
  • 1
  • 1
Ralf
  • 14,655
  • 9
  • 48
  • 58
140

Before SDK 11, a way to do this is like so:

public void reload() {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);
    startActivity(intent);
}
Jared Rummler
  • 37,824
  • 19
  • 133
  • 148
Ben
  • 16,124
  • 22
  • 77
  • 122
  • On HTC Desire animations still remain (at least when used in onConfigurationChanged method). They don't occur always, but using EboMike's code they also don't occur always. – Juozas Kontvainis Aug 19 '11 at 08:16
  • 8
    This doesn't work on the main activity started by the launcher. Your activity will end up hidden because of some of the flags set on the intent. Otherwise it works nicely. – Thomas Ahle Sep 23 '11 at 08:37
  • Good point. makes sense because it calls finish() from the base activity in the stack. – Ben Jan 25 '12 at 07:39
  • Calling this while we change the theme of the Activity seems to bring out the speed (without animations) – Ashok Goli Jun 09 '12 at 09:00
  • 3
    +1 Works fine, for me even with the main Activity. However, you should call `overridePendingTransition(0, 0);` after `finish()` and `startActivity()`, respectively, not where you called it ... – caw Jun 18 '13 at 15:58
  • @MarcoW. is correct, check the docs for `overridePendingTransition()`. – Alex Lockwood Jun 18 '13 at 19:31
  • what if the previous activity called this one using startActivityForResult ? – android developer Aug 14 '13 at 13:55
  • yeah that would not behave properly then. @Ralf's answer below is now the way you should do this. – Ben Aug 14 '13 at 23:58
118

Just to combine Ralf and Ben's answers (including changes made in comments):

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);
}
JustinMorris
  • 7,259
  • 3
  • 30
  • 36
  • 8
    Best answer of all. Believe it or not though, I'm still supporting API 3 devices, and the VERSION.SDK_INT value requires API 4. :) – Edward Falk Jan 11 '14 at 21:53
39

I used this code so I still could support older Android versions and use recreate() on newer Android versions.

Code:

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

Sample:

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());
        }
    }
}
Thomas Vos
  • 12,271
  • 5
  • 33
  • 71
27

This is by far the easiest way to restart the current activity:

finish();
startActivity(getIntent());
code
  • 2,115
  • 1
  • 22
  • 46
25

I wonder why no one mentioned Intent.makeRestartActivityTask() which cleanly makes this exact purpose.

Make an Intent that can be used to re-launch an application's task * in its base state.

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

This method sets Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK as default flags.

Tom Taylor
  • 3,344
  • 2
  • 38
  • 63
shkschneider
  • 17,833
  • 13
  • 59
  • 112
24

This solution worked for me.

First finish the activity and then start it again.

Sample code:

public void restartActivity(){
    Intent mIntent = getIntent();
    finish();
    startActivity(mIntent);
}
Community
  • 1
  • 1
user3748515
  • 261
  • 2
  • 3
20

Call this method

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

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

Thanks,

Nikhil Dinesh
  • 3,359
  • 2
  • 38
  • 41
16

Even though this has been answered multiple times.

If restarting an activity from a fragment, I would do it like so:

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

So you might be thinking this is a little overkill? But the Handler posting allows you to call this in a lifecycle method. I've used this in onRestart/onResume methods when checking if the state has changed between the user coming back to the app. (installed something).

Without the Handler if you call it in an odd place it will just kill the activity and not restart it.

Feel free to ask any questions.

Cheers, Chris

Chris.Jenkins
  • 13,051
  • 4
  • 60
  • 61
  • 2
    Great solution and very good reasoning/explanation for the Handler. – JRomero Dec 24 '12 at 06:44
  • 1
    Why do you call twice to "overridePendingTransition" ? – android developer Apr 20 '14 at 12:41
  • 1
    @androiddeveloper I can't remember, I think it was a work around to a bug. You can call it once before startActivity() and it will do as told. – Chris.Jenkins Apr 22 '14 at 14:30
  • After implementing this in my onResume function, the game stops on my onStop method and has a black screen... not sure why – Scumble373 Aug 20 '14 at 20:13
  • @Scumble373 that could be due to many many reasons. We finish the activity here then start it again. it could be OpenGL throwing a wobbly, well out of scope on this question/answer. I recommend you open a new question and reference this answer. – Chris.Jenkins Aug 27 '14 at 10:18
  • 1
    Hi chris, can you explain this a bit further "Without the Handler if you call it in an odd place it will just kill the activity and not restart it." ? – parvez rafi Aug 02 '17 at 07:11
15

Well this is not listed but a combo of some that is already posted:

if (Build.VERSION.SDK_INT >= 11) {
    recreate();   
} else {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
}
Codeversed
  • 9,287
  • 3
  • 43
  • 42
  • It works for me .. thanks .. but I want to ask you: why when i remove the first part of the code (the one that checks the SDK_INT) my app runs, relatively, slow ?!! .. when I re-attach the code again it runs, relatively and obviously, much faster !!! – McLan Nov 22 '13 at 11:12
  • 2
    Not sure on that. Well, if you are using an SDK that is >= 11 then recreate() should be faster than getting intent, finishing, then starting it again. Finish calls code that runs to onStop and recreate runs code like orientation change... so it's not quite as much to do. – Codeversed Nov 25 '13 at 01:57
14

If anybody is looking for Kotlin answer you just need this line.

Fragment

startActivity(Intent.makeRestartActivityTask(activity?.intent?.component))

Activity

startActivity(Intent.makeRestartActivityTask(this.intent?.component))
OhhhThatVarun
  • 3,981
  • 2
  • 26
  • 49
4

There is one hacky way that should work on any activity, including the main one.

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

When orientation changes, Android generally will recreate your activity (unless you override it). This method is useful for 180 degree rotations, when Android doesn't recreate your activity.

Achal Dave
  • 4,079
  • 3
  • 26
  • 32
4

In conjunction with strange SurfaceView lifecycle behaviour with the Camera. I have found that recreate() does not behave well with the lifecycle of SurfaceViews. surfaceDestroyed isn't ever called during the recreation cycle. It is called after onResume (strange), at which point my SurfaceView is destroyed.

The original way of recreating an activity works fine.

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

I can't figure out exactly why this is, but it is just an observation that can hopefully guide others in the future because it fixed my problems i was having with SurfaceViews

Community
  • 1
  • 1
The4thIceman
  • 3,709
  • 2
  • 29
  • 36
4

The solution for your question is:

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

You need to cast to activity context to start new activity and as well as to finish the current activity.

Hope this helpful..and works for me.

Rajesh Peram
  • 1,128
  • 8
  • 10
3
public void onRestart() {
    super.onRestart();
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    finish();
    act.startActivity(intent);
}

try to use this ..

Edward Falk
  • 9,991
  • 11
  • 77
  • 112
Amsheer
  • 7,046
  • 8
  • 47
  • 81
3

Actually the following code is valid for API levels 5 and up, so if your target API is lower than this, you'll end up with something very similar to EboMike's code.

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
overridePendingTransition(0, 0);
Sandy
  • 2,572
  • 7
  • 40
  • 61
1

If you remove the last line, you'll create new act Activity, but your old instance will still be alive.

Do you need to restart the Activity like when the orientation is changed (i.e. your state is saved and passed to onCreate(Bundle))?

If you don't, one possible workaround would be to use one extra, dummy Activity, which would be started from the first Activity, and which job is to start new instance of it. Or just delay the call to act.finish(), after the new one is started.

If you need to save most of the state, you are getting in pretty deep waters, because it's non-trivial to pass all the properties of your state, especially without leaking your old Context/Activity, by passing it to the new instance.

Please, specify what are you trying to do.

Dimitar Dimitrov
  • 16,032
  • 5
  • 53
  • 55
  • 1
    I have a button that applies different themes to the app, after the theme is applied, it's saved in preference, the root activity restarts, reads the theme from preference, applies the theme in onCreate(). It turns out that the above code works fine if the activity is not single_instance. Not sure if that's the best practice. –  Sep 09 '09 at 18:11
  • Currently, there is no clean, SDK-paved way to restart your Activity, AFAIK - if you don't leak anything, you may be good to go :) – Dimitar Dimitrov Sep 09 '09 at 20:04
0

Simple way is

    public void restartActivity(){
    Intent i = getIntent();
    finish();
    startActivity(i);
}
Shakthi
  • 15
  • 9
0

Kotlin way:

fun Activity.restartActivity() {
    if (Build.VERSION.SDK_INT >= 11) {
        recreate()
    } else {
        finish()
        startActivity(getIntent())
    }
}
Akshay
  • 73
  • 8
-1

If you are calling from some fragment so do below code.

Intent intent = getActivity().getIntent();
getActivity().finish();
startActivity(intent);
Mihir Trivedi
  • 1,458
  • 18
  • 39
-1

This is the way I do it.

        val i = Intent(context!!, MainActivity::class.java)
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        startActivity(i)
MicroRJ
  • 175
  • 11
-5

Call the method onCreate. For example onCreate(null);

kike0kike
  • 119
  • 7