Android activity 中的多个 onStop / onResume 调用
Multiple onStop / onResume calls in Android activity
背景
将我的应用程序置于后台时(在我的 Android phone 上的其他地方导航),onStop()
被调用一次,正如预期的那样 (Activity lifecycle)
问题原因:onStop() 包含开发人员希望 运行 一次的代码。
问题
为什么,如果我在我的应用程序 activity 中锁定我的 phone(按一次电源按钮)- onStop()
被调用了 3 次?
更新
案例#1
05-28 14:06:29.322 24347-24347/com... D/DEBUG: onCreate
05-28 14:06:29.380 24347-24347/com... D/DEBUG: onStart
05-28 14:06:29.380 24347-24347/com... D/DEBUG: onResume
虽然 activity 正在 运行ning,但我在应用之外的其他地方导航:
05-28 14:06:31.954 24347-24347/com... D/DEBUG: onStop
此时我导航回应用程序并打开它:
05-28 14:06:34.314 24347-24347/com... D/DEBUG: onStart
05-28 14:06:34.314 24347-24347/com... D/DEBUG: onResume
案例#2
05-28 14:09:01.411 24347-24347/com... D/DEBUG: onCreate
05-28 14:09:01.453 24347-24347/com... D/DEBUG: onStart
05-28 14:09:01.453 24347-24347/com... D/DEBUG: onResume
此时我锁定了我的设备:
05-28 14:35:55.017 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.278 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:55.367 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:55.411 30961-30961/com... D/DEBUG: onStart
05-28 14:35:55.419 30961-30961/com... D/DEBUG: onResume
05-28 14:35:55.440 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.441 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:55.451 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:55.493 30961-30961/com... D/DEBUG: onStart
05-28 14:35:55.502 30961-30961/com... D/DEBUG: onResume
05-28 14:35:55.830 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.969 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:56.004 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:56.044 30961-30961/com... D/DEBUG: onStart
05-28 14:35:56.052 30961-30961/com... D/DEBUG: onResume
我解锁它以查看仍然存在的 activity:
05-28 14:39:38.225 30961-30961/com... D/DEBUG: onResume
05-28 14:39:38.415 30961-30961/com... D/DEBUG: onStop
05-28 14:39:38.416 30961-30961/com... D/DEBUG: onDestroy
05-28 14:39:38.465 30961-30961/com... D/DEBUG: onCreate
05-28 14:39:38.610 30961-30961/com... D/DEBUG: onStart
05-28 14:39:38.624 30961-30961/com... D/DEBUG: onResume
不确定是否相关,但 activity 使用 VLC 库播放视频。无论视频当前是否正在播放,结果都是一样的。
更新
我的activity,在AndroidManifest.xml
中定义为android:screenOrientation="sensorLandscape"
。一旦删除 属性 (android:screenOrientation="unspecified"
),问题就会消失。
指出了正确的问题
activity被破坏和重建的原因类似于改变方向。
我的 activity 正在使用 android:screenOrientation="sensorLandscape"
,我不知道 "orientation" 在销毁 activity 时可能会发生变化。
我的应用程序同时依赖于 onStop() 和 onResume() 调用,因此我将实现 onResume(),因为它们很相似。
解决方案基于Saving the Instance State
private boolean onResumeCalledAlready;
private String ON_RESUME_CALLED_PREFERENCE_KEY = "onResumeCalled";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Record onResume not called yet
if (savedInstanceState != null) {
// Restore value of members from saved state
onResumeCalledAlready = savedInstanceState.getBoolean(ON_RESUME_CALLED_PREFERENCE_KEY);
} else {
onResumeCalledAlready = false;
}
}
@Override
protected void onResume() {
super.onResume();
if (!onResumeCalledAlready) {
onResumeCalledAlready = true;
// Do once
callMeOnlyOnce();
}
// Everything else might be called multiple times
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// Save current onResumeCalledAlready state
outState.putBoolean(ON_RESUME_CALLED_PREFERENCE_KEY, onResumeCalledAlready);
super.onSaveInstanceState(outState);
}
背景
将我的应用程序置于后台时(在我的 Android phone 上的其他地方导航),onStop()
被调用一次,正如预期的那样 (Activity lifecycle)
问题原因:onStop() 包含开发人员希望 运行 一次的代码。
问题
为什么,如果我在我的应用程序 activity 中锁定我的 phone(按一次电源按钮)- onStop()
被调用了 3 次?
更新
案例#1
05-28 14:06:29.322 24347-24347/com... D/DEBUG: onCreate
05-28 14:06:29.380 24347-24347/com... D/DEBUG: onStart
05-28 14:06:29.380 24347-24347/com... D/DEBUG: onResume
虽然 activity 正在 运行ning,但我在应用之外的其他地方导航:
05-28 14:06:31.954 24347-24347/com... D/DEBUG: onStop
此时我导航回应用程序并打开它:
05-28 14:06:34.314 24347-24347/com... D/DEBUG: onStart
05-28 14:06:34.314 24347-24347/com... D/DEBUG: onResume
案例#2
05-28 14:09:01.411 24347-24347/com... D/DEBUG: onCreate
05-28 14:09:01.453 24347-24347/com... D/DEBUG: onStart
05-28 14:09:01.453 24347-24347/com... D/DEBUG: onResume
此时我锁定了我的设备:
05-28 14:35:55.017 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.278 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:55.367 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:55.411 30961-30961/com... D/DEBUG: onStart
05-28 14:35:55.419 30961-30961/com... D/DEBUG: onResume
05-28 14:35:55.440 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.441 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:55.451 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:55.493 30961-30961/com... D/DEBUG: onStart
05-28 14:35:55.502 30961-30961/com... D/DEBUG: onResume
05-28 14:35:55.830 30961-30961/com... D/DEBUG: onStop
05-28 14:35:55.969 30961-30961/com... D/DEBUG: onDestroy
05-28 14:35:56.004 30961-30961/com... D/DEBUG: onCreate
05-28 14:35:56.044 30961-30961/com... D/DEBUG: onStart
05-28 14:35:56.052 30961-30961/com... D/DEBUG: onResume
我解锁它以查看仍然存在的 activity:
05-28 14:39:38.225 30961-30961/com... D/DEBUG: onResume
05-28 14:39:38.415 30961-30961/com... D/DEBUG: onStop
05-28 14:39:38.416 30961-30961/com... D/DEBUG: onDestroy
05-28 14:39:38.465 30961-30961/com... D/DEBUG: onCreate
05-28 14:39:38.610 30961-30961/com... D/DEBUG: onStart
05-28 14:39:38.624 30961-30961/com... D/DEBUG: onResume
不确定是否相关,但 activity 使用 VLC 库播放视频。无论视频当前是否正在播放,结果都是一样的。
更新
我的activity,在AndroidManifest.xml
中定义为android:screenOrientation="sensorLandscape"
。一旦删除 属性 (android:screenOrientation="unspecified"
),问题就会消失。
指出了正确的问题
activity被破坏和重建的原因类似于改变方向。
我的 activity 正在使用 android:screenOrientation="sensorLandscape"
,我不知道 "orientation" 在销毁 activity 时可能会发生变化。
我的应用程序同时依赖于 onStop() 和 onResume() 调用,因此我将实现 onResume(),因为它们很相似。
解决方案基于Saving the Instance State
private boolean onResumeCalledAlready;
private String ON_RESUME_CALLED_PREFERENCE_KEY = "onResumeCalled";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Record onResume not called yet
if (savedInstanceState != null) {
// Restore value of members from saved state
onResumeCalledAlready = savedInstanceState.getBoolean(ON_RESUME_CALLED_PREFERENCE_KEY);
} else {
onResumeCalledAlready = false;
}
}
@Override
protected void onResume() {
super.onResume();
if (!onResumeCalledAlready) {
onResumeCalledAlready = true;
// Do once
callMeOnlyOnce();
}
// Everything else might be called multiple times
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// Save current onResumeCalledAlready state
outState.putBoolean(ON_RESUME_CALLED_PREFERENCE_KEY, onResumeCalledAlready);
super.onSaveInstanceState(outState);
}