活动生命周期给我带来了麻烦。
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通知,并发现了一些额外的怪异:
onRestart()
。相反,它会调用onCreate()
。这对我来说很奇怪,但好吧...... onStop()
。退出usb存储活动时,返回主活动会调用onRestart()
,而不是onCreate()
。onPause()
和onResume()
周期。最后一点是预期的(虽然我不能让它适合生命周期图)。但最重要的是1.和2.?
在第一点,我期待在再次开始活动时调用onRestart()
。为什么要取消分配活动并改为呼叫onCreate()
?
看看第2点:
根据文档:当“另一项活动出现在活动前”时,应调用onPaused()
。这不是USB存储活动出现时发生的事情吗?它没有调用onPause()
,它经历了onStop()
- OnRestart()
周期!显然,文档没有考虑“另一项活动出现在活动前”的情况。那真的发生了什么?
答案 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()
检测状态栏下拉