Android应用程序组件销毁和重新创建的详细信息
有人可以向我提供有关以下内容的一些具体的、值得信赖的(最好是简洁的)信息:
系统销毁和(如果适用)重新创建组件的顺序 (片段、活动、活动的线程/异步任务/计时器、 静态数据(类何时卸载?),其他类中的线程/异步任务/定时器,主机 TabActivity、ActivityGroup、绑定本地Services、Application、进程) 无论应用程序在后台还是在前台。
在哪些点上破坏可以停止(可以遇到什么状态 返回应用程序后 - 就像“包括应用程序对象在内的所有内容 顺序是否有可能(不修改 Android)以编程方式导致相同类型的破坏 ,这样它与系统执行此操作时无法区分,或者当我们自己选择释放内存(由 onLowMemory 触发)时需要一个单独的机制?
1) 中所有场景的可靠再现步骤(junit.framework 会做吗?我还没有研究过)?
"如果用户长时间离开任务,系统清除除根活动之外的所有活动的任务。当用户再次返回任务时,仅恢复根活动”:这是与流程/组件生命周期/销毁无关,还是与之相关?
我读过各种来源提供的信息,通常不完整且具有误导性,有时甚至是不正确的。
我承认,我浏览了文档的某些部分,所以我可能错过或误解了某些内容。
[编辑]为了避免误解:我要问的是 Android 销毁组件以释放内存,绕过 Activity.onDestroy。
当我将应用程序放在后台并稍后返回时,将发生以下序列之一:
- onPause、onStop、onRestart、onStart、onResume
- onPause、onStop、Application.onCreate、onCreate(notNull)、onStart、onResume
[编辑2 ] 赏金活动开始了。需要以下方面的可靠信息:活动、片段、应用程序、绑定(可能是远程)服务、流程。
部分/全部破坏场景。参见第一点。
Could someone push me in the direction of some concrete, trustworthy (and preferably concise) information on the following:
The order in which components are destroyed and (where applicable)recreated by the system
(Fragment, Activity, Activity's Threads/AsyncTasks/Timers,
static data(when are classes unloaded?), Threads/AsyncTasks/Timers in other classes, host
TabActivity, ActivityGroup, bound local Services, Application, process)
both when the app is in the background, and in the foreground.
At which points the destruction can stop (what states can be encountered
upon return to the app - like "everything including the Application object
destroyed, process alive"?Is it possible (without modifying Android) to programmatically cause the same kind of destruction
ourselves, so that it is indistinguishable from when the system does it, or is a separate mechanism needed for when we ourselves choose to free memory (triggered by onLowMemory)?Reliable reproduction steps of all scenarios from 1) (would junit.framework do? I haven't investigated that) ?
"If the user leaves a task for a long time, the system clears the task of all activities except the root activity. When the user returns to the task again, only the root activity is restored": is this aside from the process/component lifecycle/destruction, or tied to it?
I have read various sources give pieces of information, often incomplete and misleading, sometimes incorrect.
I admit, I have skimmed over some parts of the documentation, so i may have missed or misunderstood something.
[EDIT] To avoid misunderstandings: What I am asking about is Android destroying components to free memory, bypassing Activity.onDestroy.
When I put the app in the background and return later, the one of these sequences will occur:
- onPause, onStop, onRestart, onStart, onResume
- onPause, onStop, Application.onCreate, onCreate(notNull), onStart, onResume
[EDIT2]
Bounty started. Need reliable info on: Activities, Fragments, Application, bound (potentially remote)Services, process.
Partial/full destruction scenarios. See 1st point.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这就是我的经验以及我询问过的开发人员的经验似乎表明:
示例:选项卡下带有 ActivityGroups 的 TabActivity。所有活动均实时直播。另一个活动已启动,全屏。 TabActivity 及其中的所有内容现在都可以被 Android 销毁,无论是一次性销毁还是根本不销毁。
如果您手动销毁 Activity,它会经历整个生命周期,并且在再次启动时不会将 Bundle 传递给 onCreate。
此外,onLowmemory 并不可靠 - 即使分配步骤很小,在抛出 OutOfMemoryError 之前也可能永远不会调用它。
尽管自动销毁/恢复是 Android 中的一个主要功能,但没有任何方法可以测试此类场景。
以上包括一些假设。
我仍在等待有人确认并提供一些文档(保证不依赖于类的当前实现)。
如果有任何错误,请纠正我。
编辑:以上信息可能已过时,在Android 2.1-2.3上测试
This is what my experience, and that of devs I've asked, seems to suggest:
Example: a TabActivity with ActivityGroups under tabs. All Activities live. Another Activity is started, fullscreen. The TabActivity with everything in it is now eligible for destruction by Android, all at once or not at all.
If you destroy an Activity manually, it goes through the entire lifecycle and doesn't pass a Bundle to onCreate when started again.
Also, onLowmemory is unreliable - even with small allocation steps, it might never be called before OutOfMemoryError is thrown.
Despite the autodestruction/restoration being such a major feature in Android, there isn't any way to test such scenarios.
The above include some assumptions.
I am still waiting for someone to confirm it and supply some docs (guarantees not dependent on the current implementation of classes).
Please, PLEASE correct me if any of this is wrong.
Edit: The above information may be out of date, it was tested on Android 2.1-2.3
这要归功于 hackbod 编写它此处(阅读全文答案),以及 CommonsWare 以在评论中链接。
简而言之:所有文档,重写了很多次,继续对我们撒谎。他们没有误导,他们只是向我们提供了不真实的信息。除非您使用 Fragment(不知道支持 v4 是否也算在内),否则 Android 会通过终止整个进程来释放内存,或者不执行任何操作。
当然,这并不能解决所有问题:
不过,我们已经取得了一些进展。
Credit for this goes to hackbod for writing it here(read the whole answer), and to CommonsWare for linking in a comment.
In short: All the docs, rewritten many times, continue to lie to us. They're not misleading, they just give us untrue information. Unless you're using Fragments (dunno if support v4 counts, too), Android frees memory by killing the whole process, or does nothing.
Of course, this does not address everything:
We're getting somewhere, though.
嗯,我的朋友,
我想你的研究会遇到很多麻烦。基本上是因为你谈论的是两个黑匣子:Dalvik 垃圾收集器和 android 堆管理器。我想说的是,你不能相信 android 会遵循任何对象销毁顺序。但是,您可以相信这个生命周期将遵循[Android编程,2011]:
活动生命周期:
片段具有不同的生命周期,包括方法 onAttach、onCreateView 和 onActivityCreated 。
但是,为什么你关心对象的破坏顺序呢?我看不出您没有理由监视此类事件,但如果您确实需要,请了解有关垃圾收集器的更多信息。
Well, my friend,
I guess you'll have a lot of trouble in your research. Basically because you're talking about two black boxes: the Dalvik garbage collector and the android heap manager. I would say that you cannot trust that android will follow any order of object destruction. But, you can trust that this lifecycle is going to be followed [Programming Android, 2011]:
Activity Lifecycle:
Fragments have different lifecycles including methods onAttach, onCreateView and onActivityCreated .
But, why do you care about the objects order of destruction? I can't see no reason for you to monitor such events, but if you really need, learn more about the garbage collector.
当涉及到 Activity 时,它们只会在 Destroy() 上销毁,除非开发人员手动调用 finish() 函数,否则
Fragment 生命周期与其父 Activity 完全匹配,因此当父 Activity 在 Destroy() 上销毁时, Destroy() 上的片段也会被调用。
计时器任务将完成其工作并成为垃圾收集的候选者,一旦 Activity 创建了它们,任务就会在自己的线程中运行,与 Activity 没有关系,即使 Activity 被销毁,任务也会自行完成......
When it comes to activities, they will be only destroyed on on Destroy() until and unless developer manually calls the finish() function,
Fragment life cycle is a completely matched to its parent activity, so when parent activity destroys on on Destroy(), the fragments on Destroy() as well will be called.
Timer Tasks will finish their work and become candidates for garbage collection, once the activity creates them the task runs in its own thread, no relation with activity, even if the activity is destroyed, the task finishes itself....
这不是一个完整的答案,但我建议您在每个方法中放置 toast 消息。添加您自己的
onPause()
、onStop()
、onResume()
等,并在里面添加这样一行:You不能直接调用这些方法,但是将另一个活动移动到堆栈顶部将导致调用现有活动上的这些方法。另一件需要记住的事情是,不必在每次启动 Activity 时都调用
onCreate()
。这实际上取决于您启动 Activity 的方式,例如,如果您发送此 Intent,它将显示为调用
onNewIntent()
,而不是如果它已创建。总之,最好的事情就是观看 Toast 消息。此外,您确实需要专注于使用调试器。在每个方法上打断点就可以看到了。我确信的一件事是,您不能直接调用这些方法,例如onPause()
。另请记住,通常您不知道何时调用onDestroy()
。This is not a complete answer but what I would recommend is that you place toast messages in each of these methods. Add in your own
onPause()
,onStop()
,onResume()
, etc. and inside put a line like this:You cannot directly call these methods, however moving another activity to the top of the stack will of cause these methods on the existing activity to be called. One more thing to keep in mind is that
onCreate()
need not be called every time you start an activity. It really depends on how you start the activity, for example if you send this intentit will appear call
onNewIntent()
instead if it has already been created. In summary the best thing is just to watch the Toast messages. Also you really need to focus on using the debugger. Place a breakpoint on each method and you can see it. One thing I am sure of is that you cannot directly invoke these methods likeonPause()
. Also keep in mind that in general you don't know whenonDestroy()
will be called.