Android重写onBackPressed退出应用返回注册页问题如何解决
问题背景
开发集成SQL与Firebase的问答类应用时,设计的页面流转路径为:注册/登录Activity → 启动页 → PlayActivity。在PlayActivity中重写onBackPressed方法实现双击返回弹出确认框退出的交互逻辑,原有实现代码如下:
@Override public void onBackPressed() { if (backPressedTime + 2000 > System.currentTimeMillis()) { new AlertDialog.Builder(this) .setTitle("Do you want to exit?") .setNegativeButton("No", null) .setPositiveButton("Yes", (dialog, which) -> { setResult(RESULT_OK, new Intent().putExtra("Exit", true)); System.exit(0); }).create().show(); }else { Toast.makeText(this, "Press Again to Exit", Toast.LENGTH_SHORT).show(); } backPressedTime = System.currentTimeMillis(); }
实际运行时出现异常:点击AlertDialog弹窗中的"Yes"确认按钮后,应用并未直接退出,反而跳转回此前的注册Activity。
问题根因
异常由三个问题共同导致:
- 直接调用
System.exit(0)终止虚拟机进程的退出方式不符合Android生命周期规范,部分系统版本会将这种强制杀进程的行为判定为应用崩溃,自动恢复任务栈中残留的页面。 - 页面跳转时没有销毁前置页面:从注册页跳启动页、启动页跳PlayActivity时,没有调用
finish()方法销毁当前页,导致注册页、启动页一直残留在应用任务栈中,进程被强制终止后系统会自动拉起栈底的注册页。 - 双击判定逻辑存在bug:
backPressedTime = System.currentTimeMillis()写在了if-else判断外部,无论用户第一次按返回还是第二次按返回,都会更新时间戳,会导致双击判定失效。
修复方案
按照以下步骤修改即可解决问题:
- 修正所有前置页面的跳转逻辑,跳转成功后立刻销毁当前页面,避免无效页面残留在返回栈中:
- 注册/登录页登录成功跳转启动页时补充finish调用:
startActivity(new Intent(LoginActivity.this, SplashActivity.class)); finish(); // 销毁登录注册页,避免留在栈内- 启动页自动跳转PlayActivity时补充finish调用:
startActivity(new Intent(SplashActivity.this, PlayActivity.class)); finish(); // 销毁启动页,避免留在栈内 - 替换强制杀进程的退出逻辑,使用Android官方提供的任务栈清理API实现正常退出,修正后的
onBackPressed代码如下:// 类内成员变量,初始值设为0 private long backPressedTime = 0; @Override public void onBackPressed() { if (backPressedTime + 2000 > System.currentTimeMillis()) { new AlertDialog.Builder(this) .setTitle("Do you want to exit?") .setNegativeButton("No", null) .setPositiveButton("Yes", (dialog, which) -> { // 清空当前应用任务栈下所有关联的Activity,正常退回桌面 finishAffinity(); }).create().show(); } else { Toast.makeText(this, "Press Again to Exit", Toast.LENGTH_SHORT).show(); // 仅在第一次按返回弹提示时更新时间戳,修复双击判定bug backPressedTime = System.currentTimeMillis(); } }
如果应用适配Android 12及以上版本(targetSdkVersion >= 31),可以将
finishAffinity()替换为finishAndRemoveTask(),效果一致,执行后会彻底移除应用的任务栈,不会残留任何页面。
内容的提问来源于stack exchange,提问作者YakovMashin
相关产品推荐
相关产品推荐

