【Android必备】进程和应用程序生命周期(5)

进程和应用程序生命周期

在大多数情况下,每个Android应用程序都在其自己的Linux进程中运行。当需要运行某些代码时,会为应用程序创建此进程,并且该进程将保持运行状态,直到不再需要它为止,并且 系统需要回收其内存供其他应用程序使用。

Android的一个不寻常的基本特征是应用程序的生命周期不是由应用程序本身直接控制的。相反,它是由系统通过将系统知道正在运行的应用程序的各个部分,这些东西对用户的重要程度以及系统中可用的整体内存的组合来确定的。

重要的是,应用程序开发人员了解不同应用程序组件(特别是Activity,Service和BroadcastReceiver)影响应用程序的进程的生存期。 如果不正确使用这些组件,可能会导致系统在执行重要工作的同时终止应用程序的进程

流程生命周期错误的一个常见例子是 BroadcastReceiver当它在其BroadcastReceiver.onReceive() 方法中接收到一个Intent时启动一个线程,然后从该函数返回。一旦它返回,系统将认为BroadcastReceiver不再处于活动状态,因此,不再需要其宿主进程(除非其他应用程序组件处于活动状态)。因此,系统可能会随时终止进程以回收内存,并且这样做会终止进程中运行的衍生线程。解决这个问题的方法通常是JobService从BroadcastReceiver 安排一个,所以系统知道在这个过程中仍然有工作正在进行。

要确定哪些进程在内存不足时应该被终止,Android会根据其中运行的组件以及这些组件的状态将每个进程置于“重要性层次结构”中。这些流程类型(按重要性排序):

  1. 一个前台进程是需要什么样的用户目前正在做一个。各种应用程序组件可以使其包含的过程以不同的方式被视为前景。如果满足以下任何条件,则认为过程处于前景中:

    • 它Activity 在用户正在与之交互的屏幕顶部运行(其 onResume()方法已被调用)。
    • 它有一个BroadcastReceiver正在运行的程序(它的BroadcastReceiver.onReceive()方法正在执行)。
    • 它有一个Service当前在其回调之一执行代码(Service.onCreate(), Service.onStart(),或 Service.onDestroy())。
      系统中只会有一些这样的进程,如果内存太低,甚至这些进程无法继续运行,这些进程只会作为最后的手段被杀死。通常,此时设备已达到内存分页状态,因此需要执行此操作以保持用户界面的响应。
  2. 一个可见的过程正在做用户当前意识到的工作,所以杀死它会对用户体验产生显着的负面影响。在下列情况下,流程被视为可见:
    • 它Activity 在屏幕上运行一个对用户是可见的,但不在前台(它的 onPause()方法已被调用)。例如,如果前景活动显示为允许在其后面看到先前活动的对话框,则可能发生这种情况。
    • 它有一个Service作为前台服务运行的服务,通过Service.startForeground()(这是要求系统将服务视为用户知道的事情,或者基本上对他们可见)。
    • 它正在托管系统正在使用的用于用户知晓的特定功能的服务,例如动态壁纸,输入法服务等。
      在系统中运行的这些进程的数量比前台进程的限制更少,但仍然相对受控。这些进程被认为是非常重要的,并且不会被杀死,除非需要这样做来保持所有前台进程的运行。
  3. 一个服务的过程是一个拿着Service 已经开始与 startService()方法。虽然这些过程对用户来说不是直接可见的,但他们通常在做用户关心的事情(如后台网络数据上传或下载),所以除非没有足够的内存来保存所有内容前景和可见过程。
    长时间运行(例如30分钟或更长时间)的服务可能被降级为重要的,以允许它们的进程下降到下面描述的缓存的LRU列表。这有助于避免由于内存泄漏或其他问题而长时间运行的服务消耗大量内存,导致系统无法有效使用缓存进程。
  4. 一个缓存过程是一个当前没有必要,因此系统是免费时别处需要存储器根据需要将其杀死。在正常运行的系统中,这些是内存管理中唯一涉及的过程:运行良好的系统将始终有多个高速缓存的进程可用(以便在应用程序之间进行更高效的切换),并根据需要定期清除最旧的进程。只有在非常危急的情况下(也就是不希望出现的情况),系统才能达到所有高速缓存进程都被终止的程度,并且它必须开始查杀服务进程。
    这些进程通常包含一个或多个Activity当前对用户不可见的实例(该 onStop()方法已被调用并返回)。如果他们正确地实施了他们的活动生命周期(Activity详情参见参考资料),那么当系统杀死这样的进程时,它不会影响用户在返回到该应用程序时的体验:它可以在关联活动重新创建时恢复先前保存的状态新的过程。
    这些进程保存在一个伪LRU列表中,列表中的最后一个进程首先被杀死以回收内存。在此列表中排序的确切策略是平台的实现细节,但通常它会尝试在其他类型的进程之前保留更有用的进程(一个托管用户的home应用程序,他们看到的最后一个活动等)。还可以应用其他杀死进程的策略:对所允许的进程数量进行严格限制,限制进程可以连续缓存的时间量等。

在决定如何对流程进行分类时,系统将根据在流程中当前活跃的所有组件中找到的最重要级别来决定其决策。见Activity,Service和 BroadcastReceiver文档,了解每个组件有助于过程的整体生命周期的更多细节。每个类的文档都会更详细地描述它们如何影响其应用程序的整个生命周期。

流程的优先级也可以基于流程对其的其他依赖性来增加。例如,如果进程A已经Service与Context.BIND_AUTO_CREATE 标志绑定 或正在使用 ContentProvider进程B,那么进程B的分类至少与进程A一样重要。

Lastest Update:2018.04.17

联系我

QQ:94297366
微信打赏:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ

公众号推荐:

【Android必备】进程和应用程序生命周期(5)

猜你喜欢

转载自blog.51cto.com/4789781/2122334
今日推荐