Activity 从堆栈恢复重新创建的 activity 时未调用 onStart()
Activity onStart() not called when resuming an recreated activity from a stack
长话短说: 我目前正在开发一款小型 android 游戏。一项功能是能够更改应用程序主题。当用户更改主题时,将在整个应用程序中广播一个事件,并且所有活动活动都会调用 recreate() 以应用新主题。
问题:
假设有一堆活动:A、B、C。所有活动将按照它们打开的顺序接收事件并调用 recreate()。这些是将被调用的生命周期事件(按顺序):
- Activity A 将调用 onDestroy()、onCreate()、onStart()、onResume() 和 onPause()
- Activity B 将调用 onDestroy()、onCreate()、onStart()、onResume() 和 onPause()
- Activity C会调用onPause()、onStop()、onDestroy()、onCreate()、onStart()、onResume()。
请注意,activity A 或 B 均未调用 onStop()。 当这些活动返回时(例如按下后退按钮),当它们变得可见时它们不会调用 onStart(),但会调用 onResume()。这与 activity 生命周期文档中的说明相反。
问题:我是不是做错了什么?有没有另一种方法可以在不破坏 activity 生命周期的情况下重新启动应用程序中的所有活动?
我认为你在这里采取了错误的方法。您不应使用框架调用来更改主题。您遇到的问题是您没有像框架那样调用 onStop
,但即便如此...
您的方法不正确的主要原因是 Android 可能已经销毁了 Activity
(如果它不可见)。因此,向它发送调用框架方法的事件不仅在此时是不必要的,而且可能导致不可预测的状态和行为。甚至可能导致崩溃。
对于主题或任何 UI 组件的更改,您应该在 onResume
中处理 - 换句话说,当用户 returns 到 Activity
。这样做的一种选择是通过 startActivityForResult
传递标志。
更好的方法是,使用 sharedPreferences
(或使用其他方法)使您的主题选择保持不变,然后在 Activity
恢复时从中读取。这将确保选择正确的主题,无论用户如何到达 Activity
.
编辑:
请注意,Activity
框架方法 public
并不是因为它们应该在任何时候或由其他 类 访问,而是因为它们需要在你的应用程序。它们不打算在框架外调用。
您应该注意,在 Activity
none 的官方文档中,您调用的方法被列为 "Public Methods" (http://developer.android.com/reference/android/app/Activity.html#Activity())。您正在以不受支持的方式使用它们。但是,我指出这一点只是为了让您意识到这一点,并且这并不是解决此问题的普遍接受的方法。
这与文档完全一致。
http://developer.android.com/training/basics/activity-lifecycle/starting.html
如果您查看图表,返回到 activity 时无论如何都会调用 onResume,但 onStart 不会。
如果您想更改 UI 相关组件,则必须使用 OnResume 方法而不是重新创建所有活动。喜欢以下。
@override
onResume()
{
textview.setText("Change text When activity resumes");
}
上面的同事反应很好。
您报告的行为。 onstart 和 onResume 不被调用。我已经看到它发生在热代码交换中。值得停止应用程序并调用重建。
长话短说: 我目前正在开发一款小型 android 游戏。一项功能是能够更改应用程序主题。当用户更改主题时,将在整个应用程序中广播一个事件,并且所有活动活动都会调用 recreate() 以应用新主题。
问题: 假设有一堆活动:A、B、C。所有活动将按照它们打开的顺序接收事件并调用 recreate()。这些是将被调用的生命周期事件(按顺序):
- Activity A 将调用 onDestroy()、onCreate()、onStart()、onResume() 和 onPause()
- Activity B 将调用 onDestroy()、onCreate()、onStart()、onResume() 和 onPause()
- Activity C会调用onPause()、onStop()、onDestroy()、onCreate()、onStart()、onResume()。
请注意,activity A 或 B 均未调用 onStop()。 当这些活动返回时(例如按下后退按钮),当它们变得可见时它们不会调用 onStart(),但会调用 onResume()。这与 activity 生命周期文档中的说明相反。
问题:我是不是做错了什么?有没有另一种方法可以在不破坏 activity 生命周期的情况下重新启动应用程序中的所有活动?
我认为你在这里采取了错误的方法。您不应使用框架调用来更改主题。您遇到的问题是您没有像框架那样调用 onStop
,但即便如此...
您的方法不正确的主要原因是 Android 可能已经销毁了 Activity
(如果它不可见)。因此,向它发送调用框架方法的事件不仅在此时是不必要的,而且可能导致不可预测的状态和行为。甚至可能导致崩溃。
对于主题或任何 UI 组件的更改,您应该在 onResume
中处理 - 换句话说,当用户 returns 到 Activity
。这样做的一种选择是通过 startActivityForResult
传递标志。
更好的方法是,使用 sharedPreferences
(或使用其他方法)使您的主题选择保持不变,然后在 Activity
恢复时从中读取。这将确保选择正确的主题,无论用户如何到达 Activity
.
编辑:
请注意,Activity
框架方法 public
并不是因为它们应该在任何时候或由其他 类 访问,而是因为它们需要在你的应用程序。它们不打算在框架外调用。
您应该注意,在 Activity
none 的官方文档中,您调用的方法被列为 "Public Methods" (http://developer.android.com/reference/android/app/Activity.html#Activity())。您正在以不受支持的方式使用它们。但是,我指出这一点只是为了让您意识到这一点,并且这并不是解决此问题的普遍接受的方法。
这与文档完全一致。
http://developer.android.com/training/basics/activity-lifecycle/starting.html
如果您查看图表,返回到 activity 时无论如何都会调用 onResume,但 onStart 不会。
如果您想更改 UI 相关组件,则必须使用 OnResume 方法而不是重新创建所有活动。喜欢以下。
@override
onResume()
{
textview.setText("Change text When activity resumes");
}
上面的同事反应很好。 您报告的行为。 onstart 和 onResume 不被调用。我已经看到它发生在热代码交换中。值得停止应用程序并调用重建。