2013-01-17 106 views
102

嗨,我想知道Android如何管理内存,我无法在任何地方找到准确的答案。 假设我有一个在当前活动堆栈上有5个活动的应用程序(4个被停止,1个被恢复),没有连接服务。我按HOME按钮,以便我的所有活动都停止。 我启动了一些其他耗费内存的应用程序,整体设备内存开始不足。而问题是Android销毁活动,查杀进程

...我的应用程序会发生什么?

  1. 系统能否销毁一个或一些我的活动来恢复内存?
  2. 系统会杀死我的应用程序的整个过程吗?所有的活动都会被很好地摧毁吗?
  3. 当我完全死亡后回到我的应用程序时会发生什么?它会从开始(像第一次开始)开始,还是会尝试恢复活动到previeous状态/如果是 - 它只是堆栈顶部的一个还是全部?

UPDATE:

之前问这个问题,我已经看到了活动的生命周期几次,但它并没有回答我的问题。 我做了一些测试,我有一些答案。 DDMS中的“停止过程”是测试的一个线索。

我没有测试的回答问题1,但作为指导说:

如果活动暂停或停止,该系统可以通过从内存中删除该活动 要求它完成,或者干脆就杀掉它的 进程。

看起来,一个或多个活动可以轻轻地销毁(使用onDestroy方法)而不会终止进程。当你回到他们的时候,你会得到(onCreate + bundle)。

问题2回答:

YES。通常系统会杀死整个过程,这意味着包括活动和静态字段在内的所有数据都会被销毁。这不是很好 - 你不会为任何暂停/停止的活动获取onDestroy或finialize()。这就是为什么在onPause方法之前调用saveInstanceState()的原因。 onPause基本上是您应该保存某些内容的最后一种方法,因为在此方法之后,您永远无法看到onStop或onDestroy。系统可以杀死所有对象的进程,无论他们持有什么以及他们在做什么。

问题3回答:

,当你回到一个杀死的应用会发生什么事?

  • 在Android 2.2之前 - 应用程序将从开始启动,并启动启动器。
  • 从2.2开始 - 系统将恢复以前的应用程序状态。这是什么意思?这意味着最后可见的活动将被重新创建(onCreate + bundle)。活动堆栈会发生什么?堆叠很好,但其上的所有活动都已死亡。当您通过后退按钮返回时,它们中的每一个都将被重新创建(onCreate + bundle)。 有关于一两件事:

通常,系统清除一个任务(删除所有活动从 堆的根活动上文)在某些情况下,当用户 重新选择从该任务主屏幕。通常,如果 用户在一段时间内未访问任务,例如 30分钟,则完成此操作。

结论?

  1. 不要以为处理活动的旋转问题可以通过机器人来解决 :configChanges =“方向”。当你这样做时,你会得到许多其他的问题,你甚至不知道。
  2. 用DDMS测试你的应用程序 - 停止进程按钮。 See This
  3. 使用静态变量时要小心。不要认为当你在活动1中初始化它们时 - 你将在活动2中初始化它们。初始化全局静态的唯一安全位置是Application类。
  4. 请记住,您可能永远不会看到onStop或onDestroy。关闭文件/数据库,停止onPause中的下载程序。当你想让应用程序在BG中执行某些操作时 - 使用前台服务。

这将是它...希望我和我的essey :)帮助

+0

对于您的设想,这5项活动是来自同一个应用程序还是来自多个不同的应用程序? – dumbfingers

+0

“我有一个在当前活动堆栈上有5个活动的应用程序”当然,它们都来自我的,同一个过程应用程序。 – Mark

+3

谢谢你,这正是我的问题......你的问题和答案帮了我很多。 – craigrs84

回答

29

首先请看看这个:

img1

的onPause()调用当系统即将开始恢复以前的活动时 。这通常用于将未保存的更改提交到 持久数据,停止动画和其他可能消耗CPU的内容等。此方法的实现必须非常快,因为在此方法 返回之前,下一个活动不会恢复。如果活动返回到 前面,则返回onResume(),如果用户不可见,则返回onStop()。

onStop()当活动对用户不再可见时调用,因为其他活动已恢复并且正在覆盖此 之一。这可能是因为新的活动正在开始, 现有的活动正在这个活动之前,或这一个是 被销毁。如果此活动是 回来与用户交互,则跟随onRestart(),如果此活动 消失,则跟随onRestart()或onDestroy()。

所以,当您按下设备上的“HOME”键,当前的前台活动被放到onPause()然后onStop(),其他4应保持onStop()

根据谷歌的文档:

  • 如果屏幕前景(位于堆栈顶部)的活动处于活动状态或正在运行。
  • 如果某个活动失去了焦点但仍然可见(即,新的非全尺寸或透明活动的焦点位于您的活动的顶部),该活动已暂停。暂停的活动是完全活动的(它保留所有状态和成员信息并保持连接到 窗口管理器),但可以在极低内存 情况下由系统终止。
  • 如果一项活动被另一项活动完全遮蔽,它将被停止。它仍然保留所有状态和成员信息,但是, 用户不再可见,因此它的窗口被隐藏,并且当其他地方需要内存时,系统通常会终止其 。
  • 如果一个活动暂停或停止,系统可以通过要求完成活动或简单地终止其活动,从而从内存中删除该活动。当它再次显示给用户时,它必须完全重新启动并恢复到其以前的状态。

而且,对于该过程的生命周期:

流程生命周期 3.一种背景活性不再关键(即对用户不可见的,并已被暂停的活动),因此系统可以安全地终止其进程以回收其他前台或可见进程的内存。如果它的进程需要被终止,当用户导航回到活动(使其在 屏幕上再次可见)时,它的onCreate(Bundle)方法将使用之前在 中提供的 savedInstanceState调用onSaveInstanceState(Bundle ),以便它可以在用户最后一次离开时以相同的 状态重新启动。

以上所有报价都来自于:Android Developers Reference: Activity

据证实,该系统能摧毁非acitve活动,当你推出一些消耗内存的应用回收的回忆。您可以在您的活动中执行如下操作:isFinishing(),然后使用DDMS中的“kill”按钮检测系统正在删除哪些活动。但我想系统会首先摧毁最老的一个。然而,当“发布活动”已被回收时,保留其他活动是没有意义的。

UPDATE

这里的一些意见,我从here发现:

停止状态

当一个活动是不可见的,但仍然在内存中,我们说这是一个 停止州。停止的活动可能会被带回到前面 再次成为Running活动。或者,它可能被销毁并从内存中删除 。

系统保留活动围绕处于停止状态,因为它是 可能用户还是会想一些时间尽快回复这些活动 ,并重新启动停止活动远比 便宜从头开始的活动。这是因为我们已经将所有对象加载到内存中,并且只需将它们全部带到前台即可。

已停止的活动可以随时从内存中移除。

+3

该文档在这个问题上相当混乱,但是只有整个过程可以被杀死,而不是单个组件(活动,服务等)。请参阅:http://stackoverflow.com/questions/7536988/android-app-out-of-memory-issues-tried-everything-and-still-at-a-loss/7576275#7576275 – greg7gkb

+0

@ greg7gkb thx为提供更多引用。它有助于:) – dumbfingers

+0

这个问题应该更新与@ greg7gkb评论,它的误导性 –

1

可以在系统摧毁只有一个或我的一些活动,以恢复 内存?

是的。当需要内存时,Android会杀死在后台运行的活动。杀死一个或全部可能取决于某些条件。对于暂停或停止的实例可以使android杀死一个活动或一个进程本身。 Here活动生命周期你可以得到以下几点。我建议您完整浏览该页面。它一定会清除你的疑惑。

如果活动已失去焦点,但仍清晰可见(即新 非全尺寸或透明的活动有专注于你的 活动的顶部),它已暂停。暂停的活动是完全活动的(它保留所有状态和成员信息并保持连接到 窗口管理器),但可以在极低内存 情况下由系统终止。

如果一项活动被另一项活动完全遮蔽,则其被停止。它仍然保留所有状态和成员信息,但是,用户不再可见,因此其窗口被隐藏 ,并且在其他地方需要内存 时,它通常会被系统杀死。

如果某个活动暂停或停止,则系统可以通过要求完成该活动或简单地通过 来终止活动。当它再次显示给用户时,它必须完全重新启动并恢复到其以前的状态。


威尔系统杀死我的应用程序的全过程?所有的 活动都会被很好的销毁?

活动属于个人,而过程属于一组活动。再看看上面的第三点,它杀死了上述过程。


,当我回到我的应用程序时,它完全 杀会发生什么?

它与重启相似。再次,第三点会给你一些答案,如When it is displayed again to the user, it must be completely restarted and restored to its previous state

获取有关内存相关材料的更多信息here

编辑:
应用程序中的所有活动都在单个进程中运行。所以当一个进程被杀时,所有的活动无论是5还是10都会被杀死,即重新启动。重新启动将导致您的应用程序从一开始就没有保存的状态。

+2

链接中的信息我见过活动生命周期至少5次,但它不回答我的问题。你说的话意味着我的应用程序进程被终止 - 当我回到应用程序时,它会恢复到之前的状态。所以当我有5个停止的活动时,他们都死了(onDestroy调用)当进程被杀害?当我回到我的应用程序时,所有活动都恢复了(onCreate + bundle)或者只有堆栈顶部的一个(用户可见)? – Mark

+1

应用程序中的所有活动都在单个进程中运行。所以当一个进程被杀时,所有的活动无论是5还是10都会被杀死,即重新启动。重新启动会导致您的应用程序从一开始就没有保存状态。 – Vinay

+1

几乎如此,但不适用于2.2及更高版本。在页面顶部查看我的UPDATE。 – Mark