将OnPause和的onStop()开始活动后,马上打电话 [英] OnPause and OnStop() called immediately after starting activity

查看:211
本文介绍了将OnPause和的onStop()开始活动后,马上打电话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要打开屏幕上(如果offed方案)启动时的活动。 因此,在的onCreate,我有:

I have an activity that needs to turn screen on(if offed) when it is started. So in onCreate, I have:

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在broadcasr接收器的帮助下利用这一点,我能够引起我的活动,以显示只要它是从广播接收器开始。

Using this with help of wakelock in broadcasr receiver , I am able to cause my activity to display whenever it is started from broadcast receiver.

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

But problem is very strange, activity lifecycle calls in this manner, onPause() and onResume immediately after starting activity

  1. 的onCreate
  2. ONSTART
  3. onResume
  4. 的onPause
  5. 的onStop
  6. ONSTART
  7. onResume

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


So the problem is on start and on resume calling twice, with on stop also calling, I want to implement some logic in onStop() but, with such behavior app will not work correctly.

修改

我发现问题仅仅是由于标志FLAG_SHOW_WHEN_LOCKED。当设备被锁定。而且只有当设备被活动前开始锁定的情况。

I found problem is only due to flag FLAG_SHOW_WHEN_LOCKED. and when device is locked. and it only happens when device is locked before activity is starting.

PS我使用的报警管理与广播接收器,然后开始从广播接收器的工作。

P.S I am using alarm manager with broadcast receiver, and then starts activity from broadcast receiver.

推荐答案

  • 让我们明白,为什么生命周期方法被调用多次。

下面是记录在<一个重要code评论href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.4.4_r1/android/app/ActivityThread.java?av=f#2242">ActivityThread,它负责执行该应用程序的活动。

Here is an important code comment documented in ActivityThread, which is responsible for executing the activities of the application process.

我们实现这一目标所经历的正常启动(因为   活动希望通过onResume()的第一次运行,   显示他们的窗口之前),然后暂停,则它

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 ,活动窗口,连接到和 onAttachedtoWindow 被调用的窗口管理器。如果屏幕上,活动窗口将得到重点和 onWindowFocusChanged 调用与参数。从文档

Right after onResume, the activity window is attached to the window manager and onAttachedtoWindow is invoked. If the screen is on, the activity window will get focus and onWindowFocusChanged is invoked with true parameter. From docs:

请记住,onResume是不是最好的指标,你的   活动是用户可见;一个系统窗口,如键盘锁   可能是在前面。使用onWindowFocusChanged(布尔)肯定知道   您的活动是用户可见

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

在所报告的问题时,如果屏幕关闭。因此,活动窗口不会得到注重,导致活动的的onPause 方法越来越被称为其次是的onStop 的方法,作为活动窗口是不可见的。

In the reported issue, the screen if off. Hence activity window will not get focus, which results in activity's onPause method getting called followed by onStop method, as the activity window is not visible.

由于 WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 标志设置上的活动窗口,窗口管理器服务转向使用电源管理器API在屏幕上。以下是<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.4.4_r1/com/android/server/wm/WindowManagerService.java?av=f#2755">WindowManagerService code:

Since WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON flag is set on activity window, the window manager service turns on the screen using power manager api. Following is the WindowManagerService code:

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

在屏幕开启 ONSTART 的onPause 再次被调用。

After the screen turns on onStart and onPause are called again.

因此​​:的onCreate - ONSTART - onResume - 在onPause - 的onStop - ONSTART - 在onPause

这可以通过锁定装置,并使用亚洲开发银行命令,或日食启动该活动得到验证。

This can be verified by locking the device and starting the activity using adb command or eclipse.

  • 理想的解决方案

如果你开始在的onCreate 任务,你需要停止它在 onDestory (如果任务仍悬而未决)。同样,对于 ONSTART 这将是的onStop onResume 它将的onPause

If you start a task in onCreate you need to stop it in onDestory (if the task is still pending). Similarly for onStart it would be onStop and for onResume it would be onPause.

  • 解决方法

如果您不能按照上述协议,可以检查活动窗口的焦点在状态<一href="http://developer.android.com/reference/android/app/Activity.html#hasWindowFocus()">hasWindowFocus在的onPause 方法。通常情况下,活动窗口的焦点状态将在的onPause 真。在这样的场景画面关闭或屏幕上显示的键盘锁,活动窗口的焦点将是虚假的的onPause

If you can't follow the above protocol, you can check the status of activity window focus using hasWindowFocus in onPause method. Normally the activity window focus status will be true in onPause. In scenarios like screen is off or screen is on with keyguard displayed, the activity window focus will be false in onPause.

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
    }
}

这篇关于将OnPause和的onStop()开始活动后,马上打电话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆