当应用程序的组件启动,并且该应用程序内没有其他组件在运行,则安卓系统为该应用启动一个仅有一个线程在运行的进程。默认情况下一个应用程序内的所有组件在相同的进程和线程内运行(主线程)。如果一个应用程序的组件启动并且已经存在该应用程序对应的进程(该应用程序内其他组件已经运行),则在该进程内启动组件,在相同的线程内运行该组件。然而可以为一个应用程序内的不同组件安排不同的进程,同样可以为进程创建额外的线程。
本文档讨论安卓应用程序内进程和线程的工作机制。
进程:
默认情况下应用程序内的所有组件运行在同一进程内,大部分情况下不应该改变该情形。如果你觉得应该改变组件的进程属性,可以在配置文件内进行配置。配置文件内各种类型组件元素的入口点<activity>、<service>、<provider>、<receiver>支持android:process属性来声明该组件在哪个进程内运行。你可以通过设置该属性使每个组件运行在自己的进程内或者使部分组件共享进程。你也可以设置android:process属性使不同应用程序内的组件运行在相同的进程内---提供应用程序使用相同的Linux用户ID 和设置相同的签名。<application>元素也支持android:process属性,设置运用于所有组件的默认值。在某些情况下安卓系统可能关闭某个进程,比如在内存容量低的时候和其他更直接的为用户服务的进程的要求下。在被关闭进程内运行的组件自然被销毁掉了。在又有需要这些组件工作的情况下,该进程会再次启动。安卓系统通过衡量各个进程对用户的重要性来决定结束某个进程。例如与持有可见Activity的进程相比,系统更倾向与结束持有在屏幕上不可见Activity的进程。是否终止某个进程取决于运行在该进程内组件的状态。接下来将讨论终止某个进程的规则:
进程生命周期: 安卓系统会尽可能的维持进程的运行,但是为了给新进程和更重要的进程维持足够的内存空间系统将会结束老的进程。在决定维持哪些进程和终止哪些进程问题上 安卓系统会根据运行在各个进程内组件和这些组件的状态来将进程放入在重要性层次图内的相应位置。根据恢复系统资源的需要,系统最先终止重要性最低的进程,再 则是次最低重要性的进程,以此类推。
在进程重要性层次图内共有五个等级,以下列表将根据重要性来排列各种类型进程(第一种进程最为重要,在最晚终止)。
1.前台进程: 该进程是用户当前操作所需的,在以下任何情形下该进程都会被认为使前台进程。
(1)该进程持有用户正在进行交互的Activity。(Activity的onResume()方法已经调用过)
(2)该进程持有与用户正在进行交互的Activity绑定的Service。
(3)该进程持有运行在前台的Service --- 该Service调用了startForeground()方法。
(4)该进程持有正在运行其生命周期方法(onCreate()、onStart()、onDestroy())的Service。
(5)该进程持有正在运行onReceive()方法的BroadcastReceiver。
一般情况下,在给定的时间内只有少量的前台进程存在。他们是最后被终止的进程类型 --- 如果内存容量太低以至于无法继续维持他们的运行。通常 这时内存达到了内存分页状态,所以终止一些前台进程来保护用户界面响应的及时。
2.可见进程: 该进程不持有任何为前台组件,但仍能影响用户在屏幕上的所见。在符合以下任何情形下,进程被认为是可见进程。
(1)该进程持有的Activity不处在前台 ,但用户仍可以见到该Activity(该Activity的onPause()方法已经调用了)。例如,在前台Activity启动一个对话 框,使该 Activity处在对话框后面,但仍然可见。
(2)该进程持有与可见Activity活动关联的Service。
可见进程被认为使十分重要的,不会被终止掉除非在为了维持所有前台进程的运行而被终止掉。
3.服务进程: 该进程运行由startService()方法启动的Service,并且不处于更高的两个等级上。虽然服务进程并没有与任何用户可见的东西关联,但它处理用户所 关心的事情(例如在后台播放音乐或者从网络上下载数据)。所以系统将维持它们的运行,除非在没有足够的内存空间来维持它们和所有前台进程和所有 可见进程的运行。
4.后台进程: 该进程持有当前对用户不可见的Activity(该Activity的onStop() 方法已经被调用)。这些进程对用户体验没有直接的影响,系统可以在任何时候终止 这些进程以便回收内存空间给所有的前台进程、可见进程、服务进程使用。通常会有很多后台进程在运行,所以将它们保存在LRU列表内以保证持有用户 最后可见Activity 的进程在最后终止。如果Activity正确的实现了其生命周期方法并且保存了当前的状态,终止进程并不会对用户体验的造成视觉上的影 响。因为当用户导航回该Activity时,该Activity恢复它所有的可见状态。
5.空进程: 该进程不持有任何活动的应用程序组件。维持这种类型进程存在的唯一原因是缓存,提高下一次有组件需要在该进程内运行时的启动速度。系统经常 为了平衡进程缓存和内核缓存的系统资源而终止该进程。
安卓系统根据进程内当前处于活动状态组件的重要性,将进程排到它所能达到的最高等级。例如当一个进程持有一个Service和一个可见Activity,该进程被排到可见进程等级而不是服务进程等级。此外,一个进程可能由于其他进程依赖与它而提升它的等级。一个进程为另一个进程提供服务,则该进程的等级不会比它所服务进程的等级低。例如在进程A内的ContentProvider组件为运行在进程B内的客户端提供服务,或则进程A内的Service绑定到进程B内的一个组件,则进程A被认为至少与进程B同样重要。