126

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

... 我的申请会怎样?

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

更新:

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

我没有测试问题 1 的答案,但正如指南所说:

如果一个活动被暂停或停止,系统可以通过要求它完成或简单地终止其进程来从内存中删除该活动。

似乎可以轻轻地销毁一个或多个活动(使用 onDestroy 方法)而不杀死进程。回到它们时,您将简单地得到 (onCreate + bundle) 。

问题2答案:

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

问题 3 答案:

当你回到一个被杀死的应用程序时会发生什么?

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

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

结论?

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

就是这样......希望我帮助我的essey :)

4

2 回答 2

32

首先请看一下这个:

图像1

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

onStop()当活动不再对用户可见时调用,因为另一个活动已经恢复并覆盖了这个活动。这可能是因为正在启动一项新活动,正在将现有活动带到这个活动之前,或者这个活动正在被破坏。如果此活动返回与用户交互,则为 onRestart(),如果此活动即将消失,则为 onDestroy()。

onPause()因此,当您按下设备上的“HOME”按钮时,您当前的前台活动将被放置onStop(),其他 4 个应该保留onStop()

根据谷歌的文件:

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

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

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

以上所有引用均来自:Android开发者参考:Activity

经证实,当您启动一些消耗内存的应用程序时,系统可以销毁非活动活动并回收内存。您可以像这样实现:isFinishing()在您的活动中,然后使用 DDMS 中的“杀死”按钮来检测您的哪些活动正在被系统删除。但我猜系统会先销毁最旧的。但是,当“启动活动”被回收时,保留其他活动是没有意义的。

更新

以下是我从这里找到的一些意见:

停止状态

当一个活动不可见但仍在内存中时,我们说它处于停止状态。停止的活动可以重新回到前面,再次成为跑步活动。或者,它可以被销毁并从内存中删除。

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

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

于 2013-01-17T10:25:51.057 回答
1

系统可以只破坏我的一个或一些活动来恢复内存吗?

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

如果一个活动失去焦点但仍然可见(也就是说,一个新的非全尺寸或透明活动的焦点位于您的活动之上),它会被暂停。暂停的活动是完全活动的(它维护所有状态和成员信息并保持连接到窗口管理器),但可以在内存极低的情况下被系统杀死。

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

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


系统会杀死我的应用程序的整个过程吗?所有活动都会被很好地破坏吗?

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


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

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

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

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

于 2013-01-17T10:58:28.837 回答