如何在Android中重新启动Activity

432

如何重启Android Activity?我尝试了以下方法,但是Activity只是退出了。

public static void restartActivity(Activity act){

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

}

10
由于您在创建活动后立即调用了“act.finish();”,导致该活动退出。 - Nikhil Dinesh
1
过时的方法 - pedjjj
2
使用 recreate() 进行重新加载或重新启动 Activity。 - Akash Attal
23个回答

682

我是这样做我的主题切换器的:

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

我基本上是首先调用了finish(),然后使用了与启动此活动时完全相同的意图。这似乎解决了问题?

更新:正如Ralf在下面指出的那样,在API 11及以上版本中,Activity.recreate()是最好的选择。如果您处于API11+环境中,则应首选此方法。如果您在API 10或以下版本中,请仍然可以检查当前版本并调用上面的代码片段。(请不要忘记为Ralf的答案投票!)


9
如果你不喜欢动画,你可以像你在回答中所演示的那样将其关闭。这并不意味着我的回答本质上是错误的,只是没有展示一些额外的选项,你可以自由地添加(而且问题中也没有要求)。 - EboMike
3
我从未说过你的回答是错误的,负投票并不一定意味着错误,只是相对于其他答案来说没那么好。我并不是要夸耀自己,只是想说从用户体验的角度来看,不显示动画能更真实地提供“刷新”体验。 - Ben
31
我认为你理解有误。Downvote 表示答案错误或不好,upvote 表示答案很棒。获得 upvote 的数量表示这个答案相对于其他答案的优秀程度。我能看出你试图推销你的答案,但是你在误用系统达到这个目的。 - EboMike
9
+1 - 这对我非常有效,正如你所说,动画效果是我想要的,因此用户知道它正在重新启动。顺便说一句,当我提供一个替代问题答案时,我从不对其他用户的答案进行负面评价,尽管偶尔会在我的答案被超越时进行点赞(并不是说这里发生了这种情况,只是我做过这样的事情)。 - Michael Bray
5
EboMike和Ben:你们的解决方案都回答了提问者的问题。仅仅因为“审美”原因就对某人的答案进行投票否定,这不太好。我不建议在Stackoverflow上这样做... - ChuongPham
显示剩余5条评论

400
自API 11(Honeycomb)以来,您可以调用活动的recreate()方法(感谢this回答)。
recreate()方法的作用就像配置更改一样,如果适用,则还会调用您的onSaveInstanceState()和onRestoreInstanceState()方法。

3
如果之前的活动使用 startActivityForResult() 调用了这个活动,会发生什么? - android developer
1
如果您不需要支持低于API 11的任何内容,那么这就是正确的答案。 - Edward Falk
@EdwardFalk,支持库中有没有相应的函数可以实现这个功能? - android developer
2
这种方法不适用于所有情况。如果您在调用recreate()时有一个导航抽屉打开,则重新创建时它将保持打开状态,这意味着它会保存状态,可能不是期望的结果。 - Chapz
1
我是那个不想保存状态的人。有时候人们只是想要一个干净的重新启动,那么他们应该使用EboMike的答案。 - Kimi Chiu
调用recreate()方法后,onBackPressed()方法不再被调用。 - Ahamadullah Saikat

140

在SDK 11之前,实现此操作的方法如下:

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

8
这在由启动器启动的主活动上不起作用。由于在意图上设置了某些标志,您的活动最终会被隐藏起来。否则它可以很好地工作。 - Thomas Ahle
3
+1 对我来说很好用,即使在主 Activity 中也可以。然而,你应该在 finish()startActivity() 之后分别调用 overridePendingTransition(0, 0);,而不是在你调用它的地方... - caw
@MarcoW. 是正确的,查看 overridePendingTransition() 的文档。 - Alex Lockwood
如果上一个 Activity 使用 startActivityForResult 调用了这个 Activity,会怎么样? - android developer
是的,那样肯定无法正常运行。请看下面Ralf的回答,那才是正确的做法。 - Ben
显示剩余3条评论

118

仅仅是为了结合Ralf和Ben的答案(包括在评论中所做的更改):

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
最好的答案。信不信由你,我仍然支持API 3设备,并且VERSION.SDK_INT值需要API 4。 :) - Edward Falk

39

我使用了这段代码,以便仍然支持旧版本的Android,并在新版本的Android上使用recreate()

代码:

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

示例:

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

28

这绝对是重新启动当前活动最简单的方法:

finish();
startActivity(getIntent());

25

我不明白为什么没有人提到Intent.makeRestartActivityTask(),它能够干净地实现这个目的。

创建一个 Intent,可用于重新启动应用程序任务并将其置于基本状态。

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

这种方法将 Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK 设置为默认标志。


24

这个解决方案对我有效。

首先完成活动,然后再重新启动它。

示例代码:

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

21

调用这个方法

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

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

谢谢。


1
我认为OP想要重新启动任何活动,而不仅仅是第一个,但这对我很有帮助。 - Kristopher Johnson
1
这两个标志很重要,如果没有它们,我的情况似乎什么也做不了。 - Owen B

16

尽管此问题已经有多个答案,但如果要从片段中重新启动一个活动,则可以像这样进行:

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

你也许认为这有点过度了?但是使用Handler的方法允许你在生命周期方法中调用它。我曾在onRestart/onResume方法中使用它,当检查用户返回应用程序时状态是否已更改(安装某些东西)。

如果没有Handler,如果在奇怪的地方调用它,它会简单地杀死活动而不重新启动它。

欢迎提出任何问题。

祝好, Chris


2
很棒的解决方案,对于Handler的推理/解释非常好。 - JRomero
1
你为什么要两次调用“overridePendingTransition”? - android developer
1
@androiddeveloper 我记不清了,我想这是一个解决bug的方法。你可以在startActivity()之前调用它一次,它会按照指示执行。 - Chris.Jenkins
在我的onResume函数中实现后,游戏停在了我的onStop方法上,并出现了黑屏...不确定为什么。 - Scumble373
@Scumble373,这可能由很多原因引起。我们在此结束活动,然后重新开始。这可能是OpenGL出现了问题,在此问题/答案范围之外。我建议您开启一个新的问题并引用此答案。 - Chris.Jenkins
1
嗨Chris,你能进一步解释一下“如果没有处理程序,在奇怪的地方调用它将只会杀死活动而不重新启动它”这句话吗? - parvez rafi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接