gpt4 book ai didi

android - 开始 Activity 后立即调用 OnPause 和 OnStop()

转载 作者:IT王子 更新时间:2023-10-28 23:56:50 28 4
gpt4 key购买 nike

我有一个 Activity 需要在启动时打开屏幕(如果已关闭)。所以在 onCreate 中,我有:

this.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

在广播接收器中的唤醒锁的帮助下使用它,我可以在广播接收器启动时显示我的 Activity 。

但是问题很奇怪,activity生命周期以这种方式调用,onPause()和onResume在启动activity后立即进行

  1. onCreate
  2. onStart
  3. onResume
  4. 暂停
  5. onStop
  6. onStart
  7. onResume

所以问题在于启动和恢复调用两次,停止也调用,我想在 onStop() 中实现一些逻辑,但是这样的行为应用程序将无法正常工作。

编辑

我发现问题只是由于标志 FLAG_SHOW_WHEN_LOCKED。以及当设备被锁定时。只有在 Activity 开始之前设备被锁定时才会发生这种情况。

P.S 我正在使用带有广播接收器的警报管理器,然后从广播接收器开始 Activity 。

最佳答案

  • 让我们了解为什么会多次调用生命周期方法。

这是 ActivityThread 中记录的重要代码注释,负责执行应用进程的 Activity 。

We accomplish this by going through the normal startup (because activities expect to go through onResume() the first time they run, before their window is displayed), and then pausing it.

onResume 之后, Activity 窗口被附加到窗口管理器并调用onAttachedtoWindow。如果屏幕打开, Activity 窗口将获得焦点,并使用 true 参数调用 onWindowFocusChanged。来自 docs :

Keep in mind that onResume is not the best indicator that your activity is visible to the user; a system window such as the keyguard may be in front. Use onWindowFocusChanged(boolean) to know for certain that your activity is visible to the user

在报告的问题中,屏幕是否关闭。因此 Activity 窗口不会获得焦点,导致 Activity 的 onPause 方法被调用,然后是 onStop 方法,因为 Activity 窗口不可见。

由于在 Activity 窗口上设置了 WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 标志,因此窗口管理器服务使用电源管理器 api 打开屏幕。以下是WindowManagerService代码:

public int relayoutWindow(...) {
...
toBeDisplayed = !win.isVisibleLw();
...
if (toBeDisplayed) {
...
if ((win.mAttrs.flags
& WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
if (DEBUG_VISIBILITY) Slog.v(TAG,
"Relayout window turning screen on: " + win);
win.mTurnOnScreen = true;
}
...
if (mTurnOnScreen) {
if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
mPowerManager.wakeUp(SystemClock.uptimeMillis());
mTurnOnScreen = false;
}
...
}

屏幕打开后,再次调用onStartonPause

因此:onCreate - onStart - onResume - onPause - onStop - onStart - onPause

这可以通过锁定设备并使用 adb 命令或 eclipse 启动 Activity 来验证。

  • 理想的解决方案

如果您在 onCreate 中启动任务,则需要在 onDestory 中停止它(如果该任务仍处于挂起状态)。类似地,onStartonStoponResumeonPause

  • 解决方法

如果您无法遵循上述协议(protocol),您可以使用 hasWindowFocus 查看 Activity 窗口焦点的状态在 onPause 方法中。通常 Activity 窗口焦点状态将在 onPause 中为真。在屏幕关闭或屏幕打开并显示键盘保护的情况下, Activity 窗口焦点将在 onPause 中为 false。

boolean mFocusDuringOnPause;

public void onPause() {
super.onPause;

mFocusDuringOnPause = hasWindowFocus();
}

public void onStop() {
super.onStop();

if(mFocusDuringOnPause) {
// normal scenario
} else {
// activity was started when screen was off / screen was on with keygaurd displayed
}
}

关于android - 开始 Activity 后立即调用 OnPause 和 OnStop(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25369909/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com