Android破坏活动,杀死进程


117

您好,我想知道Android如何管理内存,却找不到任何准确答案。假设我有一个应用程序,该应用程序在当前活动堆栈上有5个活动(已停止4个并恢复了1个),没有连接服务。我按下HOME按钮,以便我的所有活动都停止。我启动了其他一些消耗内存的应用程序,并且设备的整体内存开始变低。问题是

...我的申请会怎样?

  1. 系统能否销毁我的一项或多项活动以恢复内存?
  2. 系统会杀死我的整个申请过程吗?所有活动都会被销毁吗?
  3. 当我的应用程序被全部杀死后,会如何处理?它是从一开始就开始(像第一次启动一样),还是会尝试将活动恢复到较早的状态?如果是,则-是仅堆栈顶部的活动还是所有活动?

更新:

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

我尚未测试问题1的答案,但如指南所述:

如果活动被暂停或停止,则系统可以通过要求活动结束或直接终止其进程来将其从内存中删除。

似乎可以轻而易举地破坏一个或多个活动(使用onDestroy方法)而不会终止该过程。返回它们时,您将简单地获得它们(onCreate +捆绑包)。

问题2的答案:

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

问题3的答案:

当您返回被终止的应用程序时会发生什么?

  • 在Android 2.2之前的版本中-应用程序将从开始启动,并具有启动器活动。
  • 从2.2开始-系统将恢复以前的应用程序状态。这是什么意思?这意味着将重新创建上一个可见活动(onCreate +捆绑包)。活动堆栈会发生什么?堆栈很好,但是上面的所有活动均已终止。当您使用“后退”按钮返回到它们时,将重新创建它们(onCreate + bundle)。还有一件事:

通常,在某些情况下,当用户从主屏幕中重新选择任务时,系统会清除任务(从堆栈中删除根活动上方的所有活动)。通常,如果用户在一定时间(例如30分钟)内没有访问任务,则可以执行此操作。

结论?

  1. 不要以为android:configChanges =“ orientation”可以解决处理活动轮换的问题。当您这样做时,您会遇到许多其他您根本没有意识到的问题。
  2. 使用DDMS-停止进程按钮测试您的应用程序。看这个
  3. 使用静态变量时要小心。不要以为在活动1中初始化它们时-您将在活动2中对其进行初始化。初始化全局静态变量的唯一安全位置是Application类。
  4. 请记住,您可能永远不会看到onStop或onDestroy。关闭文件/数据库,停止onPause中的下载器。如果您希望应用程序在BG中执行某些操作,请使用前台服务。

就是这样...希望我能帮助我解决问题:)


以您的假设,这5个活动是来自同一应用程序还是几个不同的应用程序?
dumbfingers 2013年

1
“我有一个在当前活动堆栈上有5个活动的应用程序”当然,它们全部来自我的一个相同的流程应用程序。
2013年

4
谢谢你,这也是我的问题。您的问题和答案对我有很大帮助。
craigrs84


@Mark:这个问题现在解决了吗?怎么样
Ameer Moaaviah

Answers:


30

首先请看一下:

img1

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

onStop()当活动不再对用户可见时调用,因为另一个活动已经恢复并且正在覆盖该活动。这可能是由于新活动正在启动,现有活动被带到该活动的前面或者该活动被销毁而发生的。如果此活动返回以与用户交互,则紧跟其后的是onRestart(),或者如果此活动将要消失,则紧随其后的是onDestroy()。

所以,当您按下设备上的“HOME”键,您当前的前景活动放到onPause()随后onStop(),其他4仍应onStop()

根据Google的文件:

  • 如果某个活动位于屏幕的前台(位于堆栈顶部),则该活动处于活动状态或正在运行。
  • 如果某项活动失去了焦点但仍然可见(即,一个新的非全尺寸或透明的活动将焦点放在了您的活动之上),则该活动将被暂停。暂停的活动是完全活动的(它保留所有状态和成员信息,并仍附加到窗口管理器),但是在极端内存不足的情况下,系统可能会将其杀死。
  • 如果一个活动被另一个活动完全遮盖,则将其停止。它仍然保留所有状态和成员信息,但是,它对用户不再可见,因此它的窗口是隐藏的,当其他地方需要内存时,它通常会被系统杀死。
  • 如果活动被暂停或停止,则系统可以通过要求活动结束或直接终止其进程来将其从内存中删除。当再次将其显示给用户时,必须完全重新启动它并将其还原到以前的状态。

并且,对于流程生命周期:

流程生命周期 3.后台活动(用户不可见且已暂停的活动)不再重要,因此系统可以安全地终止其进程以为其他前台或可见进程回收内存。如果需要终止其进程,则当用户导航回到活动(使其再次显示在屏幕上)时,将使用之前在onSaveInstanceState(Bundle)中提供的saveInstanceState调用其onCreate(Bundle)方法。可以以用户最后一次离开时的状态重新启动。

上面所有引用均来自:Android开发人员参考:活动

可以肯定的是,当您启动一些消耗内存的应用程序时,系统可以破坏非活动活动并回收内存。您可以执行以下操作:isFinishing()在您的活动中,然后使用DDMS中的“杀死”按钮来检测系统正在丢弃的活动。但是我想这个系统将首先销毁最古老的系统。但是,当“启动活动”被回收时,没有必要保留其他活动。

更新

我从这里发现了一些意见:

停止状态

当活动不可见但仍在内存中时,我们说它处于停止状态。停止的活动可以带回到最前面,再次成为“正在运行”活动。或者,它可能被破坏并从内存中删除。

该系统使活动保持在停止状态,因为用户很可能仍会希望不久后回到这些活动,并且重新开始已停止的活动比从头开始活动要便宜得多。那是因为我们已经将所有对象加载到内存中了,只需要将它们全部带到前台即可。

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


4
文档在这个问题上非常令人困惑,但是只能杀死整个过程,不能杀死单个组件(活动,服务等)。请参阅:stackoverflow.com/questions/7536988/...
greg7gkb

这个问题应该使用@ greg7gkb评论链接中的信息进行更新,该评论具有误导性
Luke De Feo

1

系统能否销毁我的一项或多项活动以恢复内存?

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

如果某项活动失去了焦点但仍然可见(即,一个新的非全尺寸或透明的活动将焦点放在了您的活动之上),则该活动将被暂停。暂停的活动是完全活动的(它保留所有状态和成员信息,并仍附加到窗口管理器),但是在极端内存不足的情况下,系统可能会将其杀死。

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

如果活动被暂停或停止,则系统可以通过要求活动结束或直接终止其进程来将其从内存中删除。当再次将其显示给用户时,必须完全重新启动它并将其还原到以前的状态。


系统会杀死我的整个申请过程吗?所有活动都会被销毁吗?

活动与个人有关,而过程与活动组有关。再次看上面的第三点,它杀死了提到的过程。


当我的应用程序被全部杀死后,会如何处理?

它类似于重启。同样,第三点会给你一些答案,例如When it is displayed again to the user, it must be completely restarted and restored to its previous state

在此处获取有关内存相关内容的更多信息

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


2
我见过活动生命周期至少5次,但没有回答我的问题。您所说的意思是当我的应用程序进程被杀死时-当我返回到应用程序时,它将恢复到之前的状态。因此,当我有5个停止的活动时..当进程被杀死时,它们是否都死了(调用onDestroy)?当我回到我的应用程序时,是否还原了所有活动(onCreate +捆绑包)或仅堆栈顶部的一个活动(用户可见)?
2013年

1
应用程序中的所有活动都在单个过程中运行。因此,当一个进程被杀死时,无论是5还是10,所有活动都将被杀死,即重新启动。重新启动会导致应用程序从一开始没有保存的状态开始..
维奈

1
几乎是正确的,但不适用于2.2及更高版本。请参阅页面顶部的我的UPDATE。
马克

1
不,这是不正确的,而且从未如此。它基于的文档混乱,但见:stackoverflow.com/questions/7536988/...
greg7gkb

2
@JJPA Android无法销毁单个Activity来回收内存,它只能销毁进程。请参阅参与“内存不足杀手”实现的Android核心团队成员Dianne Hackbor的以下答案:stackoverflow.com/a/7576275/1290264
bcorso
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.