在大多数情况下,每个Android应用程序都运行在它自己所在的Linux进程中。这个进程在应用运行起来的时候被创建,而且将会存活到这个应用不再被使用或者系统内存不足需要回收掉该应用的内存空间以供其他应用使用。

Android的一个基本特性就是应用的进程的存活时间不是受应用直接控制的。而是通过系统对所有正在运行的应用的多个方面进行比对,究竟哪些对用户来说是重要的,以及系统中可用的内存是多少决定的。

开发者必须了解应用中不同的组件(尤其是Activity,Service,BroadcastReceiver)对应用的进程存活所造成的影响。如果不是以正确的使用方式使用这些组件,将会在应用做重要工作时被系统所终结(kill)。

一个典型的错误使用例子就是BroadcastReceiver的onReceive方法中启动一个线程。而当BroadcastReceiver接收到相应的广播且返回onReceive方法时这个BroadcastReceiver就不处在活跃状态了(no longer active),那么这个BroadcastReceiver所在的进程就不再被需要了(除非还有应用的其他组件运行在这个进程中)。所以系统随时能终结(kill)这个进程去回收这块内存,而当这种情况出现时,在BroadcastReceiver中启动的线程也将被终止。为了避免这种情况的出现建议在BroadcastReceiver中使用JobService,这样系统就知道这个进程还在处理重要的工作。

为了决定在低内存的情况下哪个进程终结哪个进程,Android系统中通过进程中运行的组件和他们的状态进行”重要程度分级“(importance hierarchy)。而通过这些等级划分来进行系统对各进程的终结顺序(排序按重要-次要划分):

  1. 前台进程(foreground process):当前正在屏幕上运行,用户正在交互的进程。多种不同的应用程序组件可以实现当前进程为前台进程。当出现以下任意一种情况时系统都将视该进程为前台进程:

    • 用户正在对屏幕上的活动(Activity)进行交互(当Activity的onResume()方法被调用到之后出现的情况)
    • 当前进程中有BroadcastReceiver正在运行时(当BroadcastReceiver.onReceive()方法正在被执行的情况)
    • 当前进程中有Service正执行其回调方法时(Service.onCreate(), Service.onStart(), or Service.onDestroy()被调用)
      系统中始终只会有少数这样的进程,而且这些进程只有在内存不足以支持这些进程继续运行的时才会被终结。通常只有在设备的内存已经接近使用完时才会终结这些进程以保持用户界面的响应。
  2. 可见进程(visible process):可见进程指用户能够观察到正在运行的进程。所以当终结这些进程时可能会对用户体验造成不良影响。当出现以下情况我们视该进程为可见进程:

    • 当前进程正在屏幕上运行一个可见的Activity,但是该Activity不处于前台状态(调用了onPause()方法)。比如这个Activity弹出了一个dialog,那么这个Activity所在的进程就被称为可见进程。
    • 当前进程中正在运行通过Service.starForeground()启动的前台Service。
    • 当前进程正持有一个能被用户感知的拥有特定特征的服务,比如动态壁纸,输入法服务等。
      系统中运行的这些进程的数量少于前台进程。这些进程被认为是非常重要的,不会被终结,除非这样做是为了保持所有前台进程运行。
  3. 服务进程(service process):服务进程指的是当前进程中有通过startService()方法启动的服务。虽然这些进程对用户来说并不可见,但是这些进程还是在做着用户所关心的事(比如在后台进行上传或者下载的工作),所以系统会保证这些进程的运行除非系统内存不足以支持前台进程和可见进程的运行。
    已经运行了很长一段时间的服务(如30分钟以上)可能会将其重要程度降级。这是为了避免出现长时间运行服务时的内存泄漏或者为了保证系统有效地使用缓存进程问题以致于消耗了太多内存的情况。

    以上的翻译有点生硬,为了避免翻译出错放入原文:This helps avoid situations where very long running services with memory leaks or other problems consume so much RAM that they prevent the system from making effective use of cached processes.

  4. 缓存进程(cached process):缓存进程指的是当前并不需要的进程,系统可以在其他程序需要内存时随时将该进程终结。一个正常运行的系统中会有多个缓存进程可用(为了有效地进行应用间的切换)

    以上翻译并不完全,因为本人也不是很理解原文的意思,所以只翻译了一部分,想要了解更多请看原文。

这些进程通常持有一个或多个不可见的Activity实例(调用了onStop()方法)。当我们正确地实现了这些Activity的生命周期,那么当系统终结了这些进程并不会对用户体验造成影响:Activity在新进程中被recreate时,Activity可以恢复之前保存的状态。(通过onSaveInstanceState方法和onRestoreInstanceState()方法恢复)。

这些缓存进程被保存在pseudo-LRU列表中,这个列表会在需要回收内存时将列表中最后一个进程终结。这个列表中的排序策略是根据平台的不同实现细节来安排,但是通常来说它会尽可能多地去保留有用的进程(比如在用户界面运行的应用,用户最后看到的一个Activity等),而不是保留其他类型的进程。还有一些其他的终结进程的策略可能被应用,比如:对进程数量的控制、进程可以持续缓存的时间限制等等。

系统会将所有组件活跃的进程按照重要程度进行归类。关于组建对进程的生命周期影响具体参考Activity,Service和BroadcastReceiver文档。

一个进程的优先级有可能会被与之关联的进程的优先级所提高。举个例子,如果进程A在进程B中通过Context.BIND_AUTO_CREATE去绑定了一个Service或者正在调用ContentProvider,那么进程B的优先级至少就跟进程A的优先级一样高。

原文链接:https://developer.android.google.cn/guide/components/activities/process-lifecycle.html

更多相关文章

  1. Android 系统锁屏实现固件升级动画
  2. 关于Android系统优化的思考
  3. Android图形显示系统——上层显示1:界面绘制大纲
  4. Android菜鸟的成长笔记(22)——Android进程间传递复杂数据(AIDL)
  5. Android 系统(243)---Android进程系列第一篇---进程基础
  6. Android电话系统之概述篇
  7. Android系统体系结构分析
  8. Android进程保活-自“裁”或者耍流氓
  9. Android进程学习

随机推荐

  1. Android(安卓)Intent参数传递
  2. Android(安卓)获取缓存大小及清除
  3. Android系统基础(01)简介
  4. Android事件机制之二:onTouch详解
  5. Android中传感器Sensor的使用
  6. Andriod 环境配置以及第一个Android Appl
  7. android 调用系统相机拍照并保存照片原图
  8. Android系统的开机画面显示过程分析(11)
  9. Android(安卓)Textview实现文字颜色渐变
  10. Android(安卓)javah -jni 找不到类的解决