简体   繁体   English

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

[英]What does “visibility” refer to in the Activity Lifecycle? onPause vs onStop?

The Activity Lifecycle is giving me headaches. 活动生命周期给我带来了麻烦。 The documentation at http://developer.android.com/reference/android/app/Activity.html is so darn ambiguous when it describes the concept of visibility, that I can't figure out when onStop() is called vs onPause() . http://developer.android.com/reference/android/app/Activity.html上的文档在描述可见性的概念时非常模糊,我无法弄清楚当onStop()被调用vs onPause()

Compare the following two statements from the documentation: 比较文档中的以下两个语句:

(taken from right beneath the lifecycle diagram) (从生命周期图右下方拍摄)

The onStart() and onStop() methods can be called multiple times, as the activity becomes visible and hidden to the user. onStart()onStop()方法可以多次调用,因为活动对用户可见并隐藏。

vs VS

(further down in the blue table with the "killable" columns) (进一步在蓝色表中的“可填充”列)

onPause() Called when the system is about to start resuming a previous activity. onPause()在系统即将开始恢复上一个活动时调用。

What I'd understand from the first quote, is that onStop() is called on activity A when A is "hidden". 我从第一个引文中理解的是,当A被“隐藏”时, onStop()在活动A上被调用。 "Hidden" I'd guess is referring to when another activity B has been resumed and is completely covering actvity A . “隐藏”我猜是指另一个活动B何时恢复并且完全覆盖了活动A But the second quote then states that onPause() is called when another activity is about to start resuming. 但是第二个引用然后声明当另一个活动即将开始恢复时调用onPause() Wouldn't that completely hide activity A as well? 这不会完全隐藏活动A吗? Both cases seem to imply that that activity A becomes "hidden", no? 两种情况似乎都暗示A活动变得“隐藏”,不是吗? According to my likely faulty interpretation, onPause() and onStop() are called in identical situations. 根据我可能的错误解释,在相同的情况下调用onPause()onStop()

The documentation also seems to differ between being hidden ( onStop() gets called) and being partial visibility ( onPause() gets called). 隐藏( onStop()被调用)和部分可见性(调用onPause()之间的文档似乎也有所不同。 But when is an activity still partially visible? 但什么时候活动仍然部分可见? Do they mean literally? 它们是字面意思吗? Or can an activity still be deemed "partially visible" when it has started up a new activity (activity calls startActivityForResult and starts a date picker activity) that covers the entire screen? 或者当一个活动启动一个覆盖整个屏幕的新活动(活动调用startActivityForResult并启动日期选择器活动)时,它仍然可以被视为“部分可见”吗? Surely the activity is not going get onStop invoked? 当然,活动不会被onStop调用? Its supposed to receive a result any moment! 它应该随时收到结果!

So I'm trying to figure out what I'm not getting. 所以我想弄明白我没有得到什么。 I understand that a call to onPause is guaranteed. 我知道对onPause的调用是有保证的。 That would be when activity A loses focus (device enters sleep mode, screenlock, etc), a different activity B takes the foreground (where activity B may or may not have been initiated by activity A ). 那就是当活动A失去焦点(设备进入睡眠模式,屏幕锁定等)时,不同的活动B占据前景(其中活动B可能已经或可能没有被活动A发起)。 But at which point is the onStop() invoked on activity A ? 但是在活动A上调用了onStop()

Is it matter of how many activities have been piled ontop of activity A on the activity stack? 在活动堆栈上活动A上堆积了多少活动? Are there two different definitions of "visiblity" at play? 是否有两种不同的“可见性”定义?

Sorry about the wall of text, but I'm really frustrated :S 抱歉文字的墙,但我真的很沮丧:S

So the question stands: Precisely in which situations is an activity deemed "hidden" such that onStop() is called on it? 所以问题就在于:确切地说,哪种情况是被视为“隐藏”的活动,以便在其上调用onStop()

EDIT: 编辑:

I inserted Toast notifications in each onX method, and discovered some additional weirdness: 我在每个onX方法中插入了Toast通知,并发现了一些额外的怪异:

  1. Pressing the Home button will always call onStop(). 按Home键将始终调用onStop()。 But starting up the application won't call onRestart() . 但是启动应用程序不会调用onRestart() Instead it calls onCreate() . 相反,它调用onCreate() This seems strange to me, but ok... 这对我来说很奇怪,但好吧......
  2. When the "USB Mass Storage" activity is started on top of the main activity, onStop() is called. 在主活动之上启动“USB Mass Storage”活动时,将onStop() And when exiting the usb storage activity, returning to the main activity, onRestart() is called, instead of onCreate() . 退出usb存储活动时,返回主活动, onRestart() ,而不是onCreate()
  3. When the device goes into Sleep mode and is waken up, the activity only goes through the onPause() and onResume() cycle. 当设备进入休眠模式并被唤醒时,活动仅通过onPause()onResume()循环。

The last point was expected (although I can't get it to fit in the lifecycle diagram). 最后一点是预期的(虽然我不能让它适合生命周期图)。 But whats up with 1. and 2. ? 但最新的是1.和2.?

In the first point, I was expecting a call to onRestart() when starting the activity again. 在第一点,我期待在再次启动活动时调用onRestart() Why did it deallocate the activity and call onCreate() instead? 为什么要取消分配活动并调用onCreate()呢?

And take a look at point nr 2: According to the documentation: when "another activity comes in front of the activity", onPaused() should be called. 并看看第2点:根据文档:当“另一个活动出现在活动前”时,应该调用onPaused() Isn't that what happened when the USB Storage activity came up? 这不是USB存储活动出现时发生的事情吗? It didn't call onPause() , it went through the onStop() - OnRestart() cycle! 它没有调用onPause() ,它经历了onStop() - OnRestart()循环! Obviously, the documentation doesn't consider that a case where "another activity comes in front of the activity". 显然,文档没有考虑“另一项活动出现在活动前”的情况。 So what really happened? 那真的发生了什么?

Ok, I think I've got this now. 好的,我想我现在已经有了这个。

1. 1。

The key to the first point was this link: 第一点的关键是这个链接:

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

Its a bug. 这是一个错误。 Theres some code in the link that has completely solved the problem with new root activity instances being created, instead of just restarting the last active activity (before the home button was pressed). 链接中的一些代码已经完全解决了创建新根活动实例的问题,而不是仅仅重新启动上一个活动活动(在按下主页按钮之前)。

I put the code at the top of the onCreate method, just below the super.onCreate call: 我把代码放在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;
    }
}

Note that I added the return statement after finish so the rest of the onCreate method doesn't run in the case that the bug is detected. 请注意,我在完成后添加了return语句,因此在检测到错误的情况下,onCreate方法的其余部分不会运行。

2.& 3. 2.&3。

The key to the second and third points was these two links: 第二点和第三点的关键是这两个链接:

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

How to make Activity, not covering full screen 如何制作活动,而不是覆盖全屏

It turns out that "visibility" really is literally! 事实证明,“可见性”确实是字面上的! So when the documentation says "another activity comes in front of the activity", the activity behind the bumped activity is still partially visible. 因此,当文档说“另一项活动出现在活动前”时,碰撞活动背后的活动仍然是部分可见的。 This means that the Android Activity manager must check whether the bumped Activity is a full-screen activity or not: If it is, onStop() is called on the previous activity. 这意味着Android活动管理器必须检查碰撞的活动是否是全屏活动:如果是,则在上一个活动上调用onStop() If not, then onPaused() is called on the previous activity instead. 如果没有,则在之前的活动上调用onPaused()

This trivially explains why the USB Storage manager caused the onStop() to be called. 这简单地解释了为什么USB存储管理器导致onStop()

This also means that when device goes into sleep mode, the Activity Manager considers it a non-fullscreen activity, even though technically the main activity is completely hidden behind it. 这也意味着当设备进入睡眠模式时,活动管理器会将其视为非全屏活动,即使技术上主要活动完全隐藏在其后面。

(See the second link on how to make non-fullscreen activities ) (请参阅有关如何进行非全屏活动的第二个链接)

Interestingly, the pull-down window (with the notifications) doesn't call onPause() (nor does it call onStop() ), even though it would have made sense as a non-fullscreen activity. 有趣的是,下拉窗口(带有通知)不会调用onPause() (也不会调用onStop() ),即使它作为非全屏活动也是有意义的。 This must be some kind of exception that I'll be investigating on my own. 这必须是我将自己调查的某种例外。

This also means that the onStop()-onRestart() cycle is probably more common than the onPause()-onResume() cycle (although both must still be accounted for), since activities probably more often than not are full-screen activities (personally, I thought the documentation indicated the opposite: that onPause-onResume was more commmon, but maybe thats just me). 这也意味着onStop()-onRestart()循环可能比onPause()-onResume()循环更常见(尽管两者都必须考虑),因为活动可能更多是全屏活动(就个人而言,我认为文档表明了相反的意思:onPause-onResume更常见,但也许就是我。

Additionally, this must mean that when the main activity starts a new fullscreen activity for a result, the main activity will be first stopped and later restarted when the result-retrieveing activity is done. 此外,这必须意味着当主活动为结果启动新的全屏活动时,主活动将首先停止,然后在结果检索活动完成时重新启动。

So the only question now is how to best deal with a paused activity (meaning, it is covered by a non-fullscreen activity) that gets deallocated (although this case would be rare). 所以现在唯一的问题是如何最好地处理被解除分配的暂停活动(意思是,它被非全屏活动覆盖)(尽管这种情况很少见)。 What challenges may there be? 可能会遇到什么挑战?

But thats outside the scope of this question. 但这超出了这个问题的范围。

Finally tracked this down: you can detect the status bar pulldown using onWindowFocusChanged() 最后跟踪了这个:你可以使用onWindowFocusChanged()来检测状态栏下拉

how to use OnWindowFocusChanged method 如何使用OnWindowFocusChanged方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM