【问题标题】:Avoiding double instance of activity in android避免android中的双重活动实例
【发布时间】:2015-04-01 22:08:15
【问题描述】:

我已经完成了一个简单的基于内容的应用程序。应用程序始终以启动画面启动。 3 秒后,它从 SpalshActivity 转到 MainActivity。但是我面临一个问题。如果我在应用程序显示启动画面时按下返回按钮并再次从设备应用程序列表启动应用程序,则应用程序正常启动,但我必须按两次返回图标才能退出应用程序。因为 app 有另一个 MainActivity 实例来自之前的启动。

我怎样才能避免这种双重实例?

public class SplashActivity extends Activity {

private static int SPLASH_TIME_OUT = 2000;

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

    new Handler().postDelayed(new Runnable() {


        @Override
        public void run() {

            Intent i = new Intent(SplashActivity.this,
                    MainActivity.class);
            startActivity(i);

            finish();
        }
    }, SPLASH_TIME_OUT);
}

 }

【问题讨论】:

  • @JaredBurrows 已编辑。代码给了
  • 如果您退出应用程序,如果您点击返回按钮,它将再次运行。如果您点击主页按钮,如果将恢复您的MainActivity。你有什么问题?
  • QA 报告的一个问题,它是 - 如果我在启动应用程序的那一刻按下返回按钮,然后再次启动应用程序,应用程序将正常运行,并且在启动屏幕后将出现主要活动。但是,如果我按下后退按钮,则当前的 mainactivity 消失了,但另一个 mainactivity 实例仍然出现在屏幕上。所以我必须按两次后退按钮才能退出应用程序。
  • 贴出MainActivity和AndroidManifest.xml的源码。

标签: android android-activity


【解决方案1】:

我先总结一下症状

  • 您启动应用程序。
  • 在显示初始屏幕时按返回
  • 重新启动显示初始屏幕的应用程序,然后是 MainActivity
  • 返回显示另一个 MainActivity
  • 再次按下退出应用程序

原因是您的 postDelayed 处理程序仍然运行,即使您按下回。您的手机正在正确启动SplashActivity,但另一个MainActivity 正在从旧的SplashActivity 启动。

当您进入后台时,您需要删除您的 postDelayed 回调。保留对 Handler 的引用并致电 removeCallbacksAndMessages。我通常会在 onResume 中启动 postDelayed 并在 onPause 中删除它

或者,您可以使用FLAG_ACTIVITY_CLEAR_TOP 标志启动MainActivity。该标志表示如果MainActivity 已经存在于后堆栈中,则应将其置于最前面,并且应关闭其上方的活动。如果您希望它重复使用相同的活动实例而不是创建一个新实例,也可以添加 FLAG_ACTIVITY_SINGLE_TOP

【讨论】:

  • 谢谢解释。现在对我来说很清楚。一定会解决的。
【解决方案2】:

在您的 manifest.xml 中,添加 MainActivity:

android:launchMode="singleTop"

当您启动活动时:

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

【讨论】:

  • 如果您指定 xml 而不是通过意图在代码中指定怎么办?有关系吗?
  • @ZakTaccardi 没关系,它应该可用
【解决方案3】:

让我告诉你避免这个错误的方法:

在你的“super.onCreate(null);”之前添加这个在你的 onCreate 方法中

if (!isTaskRoot()
                && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
                && getIntent().getAction() != null
                && getIntent().getAction().equals(Intent.ACTION_MAIN)) {
            finish();
            return;
        }

super.onCreate(null);

当它不是taskroot时,它会在每次被调用时完成splashactivity。

第二个选项是去掉postdelayed,这是搞乱进程的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 2019-12-29
    • 2021-12-05
    • 1970-01-01
    相关资源
    最近更新 更多