活动生命周期中“可见性”指的是什么? onPause vs onStop?

时间:2011-12-26 23:54:01

标签: android android-activity activity-lifecycle

活动生命周期给我带来了麻烦。 http://developer.android.com/reference/android/app/Activity.html上的文档在描述可见性概念时非常模糊,我在onStop()调用onPause()时无法弄清楚。

比较文档中的以下两个陈述:

  

(取自生命周期图右下方)

     

可以多次调用onStart()onStop()方法,如   活动变得可见并隐藏给用户。

VS

  

(进一步在蓝色表格中显示“killable”列)

     

onPause()当系统即将开始恢复之前的活动时调用。

我从第一句引文中理解的是,当onStop()被“隐藏”时,A会在活动A上被调用。 “隐藏”我猜是指其他活动B何时恢复并且完全覆盖了行为A。 但是第二个引用然后指出当另一个活动即将开始恢复时调用onPause()。这不会完全隐藏活动A吗?两种情况似乎都暗示该活动A变得“隐藏”,不是吗?根据我可能的错误解释,onPause()onStop()在相同的情况下被调用。

隐藏(onStop()被调用)和部分可见性(onPause()被调用)之间的文档似乎也有所不同。但什么时候活动仍然部分可见?它们是字面意思吗?或者当一个活动启动一个覆盖整个屏幕的新活动(活动调用startActivityForResult并启动日期选择器活动)时,它仍然可以被视为“部分可见”吗?当然,活动不会被onStop调用?它应该随时收到结果!

所以我想弄明白我没有得到什么。 我知道对onPause的调用是有保证的。那就是当活动A失去焦点(设备进入睡眠模式,屏幕锁定等)时,不同的活动B占据前景(活动B可能已经或可能未被启动活动A)。 但是,在活动onStop()上调用了A

在活动堆栈上活动A上堆积了多少活动?是否有两种不同的“可见性”定义?

对于文字墙感到抱歉,但我真的很沮丧:S

所以问题就在于:确切地说,哪种情况是被视为“隐藏”的活动,以便在其上调用onStop()

修改

我在每个onX方法中插入了Toast通知,并发现了一些额外的怪异:

  1. 按主页按钮始终调用onStop()。但是启动应用程序不会调用onRestart()。相反,它会调用onCreate()。这对我来说很奇怪,但好吧......
  2. 当在主活动之上启动“USB Mass Storage”活动时,将调用onStop()。退出usb存储活动时,返回主活动会调用onRestart(),而不是onCreate()
  3. 当设备进入睡眠模式并被唤醒时,该活动仅会经历onPause()onResume()周期。
  4. 最后一点是预期的(虽然我不能让它适合生命周期图)。但最重要的是1.和2.?

    在第一点,我期待在再次开始活动时调用onRestart()。为什么要取消分配活动并改为呼叫onCreate()

    看看第2点: 根据文档:当“另一项活动出现在活动前”时,应调用onPaused()。这不是USB存储活动出现时发生的事情吗?它没有调用onPause(),它经历了onStop() - OnRestart()周期!显然,文档没有考虑“另一项活动出现在活动前”的情况。那真的发生了什么?

2 个答案:

答案 0 :(得分:2)

好的,我想我现在已经有了这个。

1

第一点的关键是这个链接:

http://code.google.com/p/android/issues/detail?id=2373

这是一个错误。链接中的一些代码已经完全解决了创建新根活动实例的问题,而不是仅仅重新启动上一个活动活动(在按下主页按钮之前)。

我把代码放在onCreate方法的顶部,就在super.onCreate调用之下:

if (!isTaskRoot()) {
    final Intent intent = getIntent();
    final String intentAction = intent.getAction();
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) &&
            intentAction != null && intentAction.equals(Intent.ACTION_MAIN)) {
        finish(); return;
    }
}

请注意,我在完成后添加了return语句,因此在检测到错误的情况下,onCreate方法的其余部分不会运行。

2&安培; 3。

第二点和第三点的关键是这两个链接:

http://answers.oreilly.com/topic/2692-android-programming-understanding-the-activity-life-cycle/

How to make Activity, not covering full screen

事实证明,“能见度”真的是字面上的!因此,当文档说“另一项活动出现在活动前”时,碰撞活动背后的活动仍然是部分可见的。这意味着Android活动管理器必须检查受影响的活动是否为全屏活动:如果是,则在上一个活动中调用onStop()。如果没有,则会在之前的活动中调用onPaused()

这简单地解释了为什么USB存储管理器导致onStop()被调用。

这也意味着当设备进入睡眠模式时,活动管理器会将其视为非全屏活动,即使从技术上讲,主要活动完全隐藏在其后面。

(请参阅有关如何进行非全屏活动的第二个链接)

有趣的是,下拉窗口(带有通知)不会调用onPause()(也不会调用onStop()),即使它作为非全屏活动也是有意义的。这必须是我将自己调查的某种例外。

这也意味着onStop()-onRestart()周期可能比onPause()-onResume()周期更常见(尽管两者都必须考虑),因为活动可能更多是全屏活动(个人,我认为文档表明相反:onPause-onResume更常见,但也许就是我。)

此外,这必须意味着当主活动为结果启动新的全屏活动时,主活动将首先停止,然后在结果检索活动完成后重新启动。

所以现在唯一的问题是如何最好地处理被解除分配的暂停活动(意思是,它被非全屏活动覆盖)(尽管这种情况很少见)。可能会遇到什么挑战?

但这不属于这个问题的范围。

答案 1 :(得分:0)

最后追踪到这一点:你可以使用onWindowFocusChanged()

检测状态栏下拉

how to use OnWindowFocusChanged method