如何在Android中重新启动Activity


381

如何重新启动Android Activity?我尝试了以下方法,但是Activity简单地退出了。

public static void restartActivity(Activity act){

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

}

9
由于您调用了“ act.finish();”而退出了活动 创建活动后立即...
Nikhil Dinesh 2013年

1
过时的方法
pedjjj

Answers:


623

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

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

基本上,我finish()首先打电话,并且我使用的是与开始此活动完全相同的意图。这似乎可以解决问题?

更新:正如下面的Ralf所指出的那样,这Activity.recreate()是API 11及其以后版本的方法。如果您使用的是API11 +环境,则更可取。如果您使用的是API 10或更低版本,您仍然可以检查当前版本并调用上面的代码段。(请不要忘记赞扬拉尔夫的答案!)


36
那值得投票吗?这不是《任择议定书》提到的要求。实际上,这可能是理想的。
EboMike

9
好吧,如果您不喜欢该动画,则可以将其关闭(如您在回答中所展示的)。这本身并不会使我的答案错误,只是没有显示您可以自由添加的其他选项(问题中没有要求)。
EboMike

28
我想你错了。下注表示错误/错误的答案,上注表示答案很好。投票数表明答案与其他答案相比有多好。我可以看到您正在尝试推广您的答案,但是您为此目的滥用了系统。
EboMike

8
+1-对我来说效果很好,正如您所说,动画是我确实想要的东西,因此用户知道它正在重新启动。FWIW,虽然我有时会在答案超出范围时偶尔投票,但我还是会永远不投票给其他用户的答案,这是一条规则(不是说发生在这里,只是因为我做到了) 。
Michael Bray

4
EboMike和Ben:您的两种解决方案都回答了OP的问题。仅仅因为“审美”原因而否定某人的答案是不好的。我不鼓励任何人在Stackoverflow上这样做……
ChuongPham

368

从API级别11(蜂窝)开始,您可以调用活动的recreate()方法(由于答案)。

recreate()方法的行为就像配置更改一样,因此,如果适用,也会调用onSaveInstanceState()和onRestoreInstanceState()方法。


3
如果上一个活动使用startActivityForResult将该活动称为该怎么办?
android开发人员

1
嗯,这是正确的答案,如果你不需要任何支持低于API 11
爱德华·福尔克

@EdwardFalk在支持库上有任何功能吗?
android开发人员

2
这并非在所有情况下都有效。如果在调用recreate()时打开了导航抽屉,则它在重新创建时将保持打开状态,这意味着它将保存状态,这可能是不希望的。
查普兹

我就是不希望保存状态的人。有时人们只想重新启动,那么他们应该使用EboMike的答案。
Kimi Chiu

132

在SDK 11之前,执行此操作的方法如下:

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

在HTC上,仍然保留Desire动画(至少在onConfigurationChanged方法中使用时)。它们不会总是发生,但是使用EboMike的代码也不会总是发生。
Juozas Kontvainis 2011年

8
这对于启动器启动的主要活动不起作用。由于意图上设置了一些标志,您的活动最终将被隐藏。否则它会很好地工作。
Thomas Ahle

好点子。之所以有意义,是因为它从堆栈的基本活动中调用finish()。
2012年

在我们更改活动主题时调用此函数似乎可以提高速度(无动画)
Ashok Goli 2012年

3
+1工作正常,即使是参加主要活动也对我而言。但是,您应该分别overridePendingTransition(0, 0);在after finish()和之后调用,而startActivity()不是在您调用它的位置...
caw 2013年

115

只是为了结合拉尔夫和本的答案(包括评论中所做的更改):

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值需要API4。:)
Edward Falk 2014年

31

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

码:

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

对我来说是很棒的工作!
PAPO

22

这个解决方案对我有用。

首先完成活动,然后重新开始。

样例代码:

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


19

调用此方法

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希望重新启动任何活动,而不仅仅是第一个活动,但这对我很有帮助。
克里斯托弗·约翰逊

1
很高兴知道这两个标志,没有它们,我的案子似乎什么也做不了。
Owen

1
它的工作感谢你!上帝祝福你 。
Vivek

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

因此,您可能会认为这有点矫kill过正?但是Handler发布允许您在生命周期方法中调用它。我在onRestart/onResume在检查用户返回应用程序之间的状态是否已更改时,方法中方法。(安装了一些东西)。

没有 Handler如果您在一个奇怪的地方调用它,它将杀死该活动,而不会重新启动它。

随意问任何问题。

克里斯,干杯


2
处理程序的绝佳解决方案和很好的推理/解释。
JRomero

1
为什么要两次调用“ overridePendingTransition”?
android开发人员

1
@androiddeveloper我不记得了,我认为这是解决错误的工作。您可以在startActivity()之前调用它一次,它将按照提示进行操作。
克里斯·詹金斯(Chris.Jenkins)2014年

在我的onResume函数中实现此功能后,游戏在我的onStop方法上停止并显示黑屏...不知道为什么
Scumble373 2014年

1
克里斯,您好,您能否进一步解释一下:“如果没有处理程序,如果您在一个奇怪的地方调用它,它将杀死该活动,而不会重新启动它。” ?
parvez rafi

15

好吧,这没有列出,而是一些已经发布的组合:

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

它对我有用..谢谢..但我想问你:为什么当我删除代码的第一部分(检查SDK_INT的那一部分)时,我的应用程序运行起来相对较慢?..当我重新附加代码时,它运行起来相对明显,显然要快得多!
McLan

2
不确定。好吧,如果您使用的SDK> = 11,那么recreate()的速度应该比意图,完成然后重新启动的速度要快。完成调用运行到onStop的代码并重新创建运行代码(例如方向更改)...因此要做的事情并不多。
2013年

4

结合奇怪的SurfaceView生命周期行为与相机。我发现recreate()在SurfaceViews的生命周期中表现不佳。在娱乐周期中从未调用surfaceDestroyed。在onResume(奇怪)之后调用它,这时我的SurfaceView被销毁了。

重新创建活动的原始方法很好用。

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

我无法弄清楚为什么会这样,但这只是一个观察,它有望在将来指导其他人,因为它解决了我在SurfaceViews上遇到的问题


4

我想知道为什么没有人Intent.makeRestartActivityTask()明确提出这一确切目的。

创建一个可用于在其基本状态下重新启动应用程序任务的Intent。

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

此方法设置Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK为默认标志。


3

实际上,以下代码对5级及以上的API有效,因此,如果您的目标API低于此级别,您将得到与EboMike的代码非常相似的东西。

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

3

有一种适用于任何活动的骇客方式,包括主要活动。

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

更改方向后,Android通常会重新创建您的活动(除非您覆盖它)。当Android不重新创建活动时,此方法可用于180度旋转。


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

尝试使用这个..


3

您问题的解决方案是:

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

您需要转换为活动上下文以启动新活动以及完成当前活动。

希望这对我有帮助。


1

如果删除最后一行,则将创建新的actActivity,但旧实例仍处于活动状态。

您是否需要像更改方向(例如,保存状态并将状态传递给onCreate(Bundle))一样重新启动“活动” ?

如果不这样做,一个可能的解决方法是使用一个额外的虚拟活动,该活动将从第一个活动开始,而哪个工作是启动该活动的新实例。或者只是延迟拨打act.finish()在新开始后。

如果您需要保存大多数状态,那么您将陷入困境,因为通过将状态的所有属性传递给新实例来传递状态的所有属性并非易事,尤其是在不泄漏旧的Context / Activity的情况下。

请指定您要做什么。


1
我有一个将不同主题应用到应用程序的按钮,在应用主题之后,将其优先保存,root活动重新启动,从偏好中读取主题,然后在onCreate()中应用主题。事实证明,如果活动不是single_instance,则上述代码可以正常工作。不确定这是否是最佳做法。

当前,没有干净的,用SDK铺砌的方法来重新启动您的活动AFAIK-如果您不泄漏任何内容,则可能会很不错:)
Dimitar Dimitrov

0

这就是我做到的方式。

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


-4

你可以简单地使用

onRestart()

方法如下

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

并在要重新启动当前活动的位置调用onRestart()


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.