【问题标题】:Does pressing Back always cause Activity to finish()?按 Back 是否总是导致 Activity 完成()?
【发布时间】:2010-05-10 07:19:20
【问题描述】:

我听说按下后退按钮实际上会导致当前 Activity 变为 finish()。总是这样吗?似乎它将与将 Activity 从堆栈中弹出的方式有关。

我不太确定的一种情况是当任务中的根 Activity 被按下时。我目前正在经历一个非常奇怪的效果,描述如下:

在加载我的应用程序时,第一个 Activity 用于初始化,一旦完成,它就会调用我的主 Activity(一个 TabActivity)。这第一个初始化活动在清单中设置了 android:noHistory="true" ,因此从我的主活动按返回不会回到那个状态。它进入启动器。当我第二次在启动器中单击我的应用程序时,初始化活动再次加载,并在完成后加载主活动。几乎立即,它加载了我的主要活动的第二个实例。但只有在应用程序已经运行一次,并通过从主 Activity 中按 BACK 退出后。它每次都会执行此操作,直到我强制退出应用程序或从 IDE 加载新版本。

基于此,我怀疑某种 Activity 实例正在周围并被重用,因为它只发生在我运行应用程序的第二次以上(并以 BACK 退出 - 使用 HOME 只是返回到最后一个状态应用程序,没什么大不了的)。有人有什么想法吗??

【问题讨论】:

    标签: android android-activity lifecycle


    【解决方案1】:

    我听说按下后退按钮本质上会导致当前 Activity 完成()。总是这样吗?

    不,不是。大多数活动都有这种行为,但不是全部。例如,您可以创建一个 Dialog 并将其设置为setCancelable(false),如果您单击 BACK 按钮,它将不会关闭。

    此外,您可以通过覆盖 onBackPressed 来自定义按下 BACK 按钮时的活动行为

    当 Activity 检测到用户按下返回键时调用。默认实现只是完成当前活动,但您可以覆盖它来做任何您想做的事情。

    关于您的应用程序行为..您是否验证了活动启动器在加载您的主要活动后是否完成?我的意思是如果调用了 onDestroy() 方法。也许在它运行主要活动之后它仍然存在,当你点击返回时,你只是回到旧的启动器......

    希望这会有所帮助..

    【讨论】:

      【解决方案2】:

      阅读Android开发者网站上的Activity and Task design guidelines;他们解释了 Home 和 Back 按钮是如何工作的。显然,如果您覆盖默认行为(如上面 hara 所述),后退按钮将不会完成活动。

      关于您的具体问题,请检查您的 logcat。您应该能够在那里看到它是使旧流程恢复生机还是启动新流程。如果不清楚,请在 onCreate、onPause、onDestroyed 等中插入一些日志语句,以便您可以准确地看到您的进程发生了什么。

      【讨论】:

      • 感谢您提供指向这些指南的链接。看起来不错,我还没有关注“最佳实践”部分。
      • 所以你从头开始创建的任何活动默认情况下都会在按下后退按钮时完成,除非你覆盖它?
      • 基本上,是的。尽管从 Android 4.0 版本开始,您可以通过多种方式影响后退按钮的行为,但这变得非常复杂。见developer.android.com/training/implementing-navigation/…
      【解决方案3】:

      您可以通过编写以下代码来控制 BACK-BUTTON。

      public boolean onKeyDown(int keyCode, KeyEvent event) 
      {
          if (keyCode == KeyEvent.KEYCODE_BACK ) {
              //preventing default implementation previous to 
              //android.os.Build.VERSION_CODES.ECLAIR
              return false;
          }     
          return super.onKeyDown(keyCode, event);    
      }
      

      【讨论】:

        【解决方案4】:

        您是否使用任何特殊标志(例如 singleInstance 或 singleTop)来运行您的活动?这些可能会导致您看到的奇怪现象。找出导致问题的最简单的方法是用调试消息完全填充它。例如:

        1. 在您的初始化活动中,在 onCreate 的开头添加一个日志以获取活动的名称,例如 this.toString()。稍后详细了解您为什么需要这条线路。
        2. 当它启动主选项卡式活动时,获取启动活动的名称和一条消息,说明它已启动选项卡式活动。
        3. 覆盖 onPause()、onStop() 和 onDestroy() 回调,并添加带有 this.toString() 的调试行以及一条告诉您它是哪个回调的消息。

        这将告诉您是否有多个初始化活动实例。为此,将调用您的主要活动的活动名称与刚刚创建的活动名称和经过 onDestroy 的活动名称进行比较。

        如果您不知道如何调试,请使用Log.d(LOG_TAG, "Your message here");。然后在某处定义一个常量 LOG_TAG 字符串。之后,通过转到Window,显示透视(或视图,不记得确切),其他,Android,LogCat,在Eclispe中显示LogCat透视图。拥有 LOG_TAG 常量的目的是您可以设置 LogCat 以过滤到该字符串并仅向您显示这些消息。这将使在大量系统日志消息中更容易看到它们。

        【讨论】:

          【解决方案5】:

          对原始问题的简短回答是“不”。不幸的是,这主要是因为并非每个开发人员都遵循先前答案所引用的准则。

          然而,当返回键不应该调用finish()时,指南本身也提到了异常。最突出的例外是 Web 浏览器,它为每个窗口都有自己的“后退堆栈”,因此它必须有自己的后退键自定义处理。

          【讨论】:

          • 我碰巧喜欢按下返回会显示“再次按下以退出”的祝酒词的应用。然后我知道我是否真的退出了。
          【解决方案6】:

          如果后退堆栈上没有片段并且开发人员没有覆盖 onBackPressed,则当按下后退按钮时,活动将结束。

          这里是Android 4.4.2 Activity.onBackPressed()的源代码:

          public void onBackPressed() {
              if (!mFragments.popBackStackImmediate()) {
                  finish();
              }
          }
          

          【讨论】:

            【解决方案7】:

            只需覆盖 onbackpressed().. 后按此方法将执行 remove super 并做你想做的事。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-02-10
              • 1970-01-01
              • 1970-01-01
              • 2016-06-06
              • 1970-01-01
              • 2019-10-04
              • 1970-01-01
              • 2021-12-12
              相关资源
              最近更新 更多