当前位置: 首页 > 知识库问答 >
问题:

开始活动后立即调用OnPause和OnStop()

壤驷穆冉
2023-03-14

我有一个活动需要在启动时打开屏幕(如果关闭)。所以在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);

使用这个与wakelock在扩频接收器的帮助下,我能够使我的活动显示,每当它从广播接收器开始。

但问题很奇怪,活动生命周期以这种方式调用,onPause()和onResume在开始活动后立即执行

  1. 创建时
  2. 开始时
  3. 继续
  4. 打开暂停
  5. onStop(停止)
  6. 开始时
  7. 继续

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

编辑

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

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

共有3个答案

班宏毅
2023-03-14

Manish Mulimani的解决方法对我有效,只是我先检查窗口焦点,然后调用super.onPause():

public void onPause() {
    mFocusDuringOnPause = hasWindowFocus();    
    super.onPause();
}

public void onStop() {
    super.onStop();
    if (mFocusDuringOnPause) {
        // normal scenario
    } else {
        // activity was started when screen was off or screen was on with keyguard displayed
    }
}
金子平
2023-03-14

android:configChanges=“keyboardHidden|orientation|screenSize”添加清单Activity中。这可能会解决你的问题。

方英耀
2023-03-14
  • 让我们了解为什么生命周期方法被多次调用。

这是ActivityThread中记录的一个重要代码注释,它负责执行应用html" target="_blank">程序进程的活动。

我们通过正常的启动(因为活动在第一次运行时,在窗口显示之前,期望通过onResume()来完成),然后暂停它。

就在onResume之后,活动窗口附加到窗口管理器并调用onattachedtoWindow。如果屏幕打开,活动窗口将获得焦点,并使用true参数调用onWindowFacusChanged。来自文档:

请记住,onResume 并不是用户可以看到您的活动的最佳指标;系统窗口(如键盘锁)可能位于前面。使用 onWindowFocusChanged(布尔值)确定您的活动对用户可见

在报告的问题中,屏幕处于关闭状态。因此,活动窗口不会获得焦点,这将导致调用活动的< code>onPause方法,然后调用< code>onStop方法,因为活动窗口不可见。

自<code>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;
        }
        ...
}

屏幕打开后,再次调用onStartonP的

因此:on创建-onStart-onResume-onP再-onStation-onStart-onP再

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

  • 理想的解决方案

如果您在on创建中启动一个任务,您需要在onTokory中停止它(如果该任务仍处于挂起状态)。类似地,对于onStart,它将是on停止,对于onResume,它将是onP的

    < li >解决方法

如果无法遵循上述协议,则可以在 onPause 方法中使用 hasWindowFocus 检查活动窗口焦点的状态。通常,活动窗口焦点状态在暂停时为 true。在屏幕关闭或屏幕打开并显示键盘锁的情况下,活动窗口焦点在暂停时将为假。

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
    }
}
 类似资料:
  • 我有一个应用程序,它是一种闹钟。我有一个奇怪的问题。 原理很简单:警报管理器发送一个广播,启动服务和活动。 该服务使手机振动10秒,然后停止活动并自行停止。该活动显示一个解除按钮。如果你点击它,它会停止服务和自身。 如果在电话打开时接收到广播,则工作正常(活动开始并且电话振动)。 如果在手机处于睡眠模式时接收到广播,则活动开始并立即停止(除非在屏幕上放置Thread.sleep)。服务很好。 我不

  • 本文向大家介绍怎么在watch监听开始之后立即被调用?相关面试题,主要包含被问及怎么在watch监听开始之后立即被调用?时的应答技巧和注意事项,需要的朋友参考一下 有个参数 https://cn.vuejs.org/v2/api/#vm-watch

  • 重试时间:io.reactivex.subjects.serializedsubject@35fb3008 subscribeNext 进程已完成,退出代码为0

  • 我想在设备重新启动后与启动通知(如消息、Viber通知、Whatsapp等)并排启动锁定屏幕活动。如何做到这一点??.我已经制作了一个广播接收器,它接收引导完成操作,然后启动一个服务,该服务再次用intent.action_screen_off和intent.action_screen_on意图过滤器注册相同的接收器,该接收器启动锁定屏幕活动。以下是我的代码: AndroidManifest.xm

  • 库中有一个从javascript(html5应用程序)调用的类。它不能是活动扩展器。该类可以访问活动和WebView对象。 是否可以从这个库类中获取onResume、on暂停和onDestroy活动事件?