5.2.2 进程优先级
应用进程各有各的特征,为了统一处理不同的应用进程,就需要抽取进程的共同特征进行归类。进程优先级是Android进程托管策略的基础。Android通过每个应用进程中的组件类型和运行特征,将进程划分为不同的优先级。优先级越高,说明该进程中运行的组件对于用户当前的状态而言越重要,相应地,系统分配给该进程的资源就越多,进程运行的时间也就越长。
如表5-1,应用进程按优先级可分为五类:前台进程、可视进程、服务进程、后台进程和空进程。进程优先级评定的主要依据是进程中的界面组件、服务组件和触发器组件的运行状况。数据源组件不会作为进程优先级评定的考量依据,因为在Android中,数据源组件的作用是提供数据存储服务,其中的数据都是可持久化的,它的运行状态并不重要。
优先级的高低,是由应用进程中组件与用户的交互状态来确定的。进程中包含的组件与用户交互越密切,该进程的优先级就越高。
当前用户进行交互的界面组件,称为前台界面组件。如果一个应用进程包含前台界面组件,或包含与前台界面组件相绑定的服务组件,那么它就隶属于前台进程。除此之外,进程中如果有正在执行关键代码的组件(比如正在调用BroadcastReceiver.onReceive函数的触发器组件),也会被归类于前台组件,因为这些组件的执行会直接影响用户体验。
在Android中,前台进程是与用户交互最紧密的进程,因此具有最高的优先级,可占据最多的系统资源。对于开发者而言,不要让组件长时间执行BroadcastReceiver.onReceive和Service.onStart等关键函数,以免使进程停留在前台状态,耗费过多的系统资源。
还有一类界面组件,它们虽然不直接和用户交互,但依然会占据用户的视觉空间,直接影响用户体验,这类组件被称为可视界面组件。如图5-3所示,此时与用户进行交互的前台界面组件是查词界面,而作为背景的浏览器界面组件就是可视组件,它依然需要正常运行,从而使用户可以根据前台界面上的词进行查询。
图 5-3 前台界面组件和可视界面组件
如果一个应用进程中包含可视界面组件,或包含绑定可视界面组件的服务组件,就称为可视进程。通常而言,系统不会回收可视进程,因为这样会严重影响用户体验。
还有一类组件可能会和用户体验有直接关联:后台服务组件。所谓后台服务组件,指的是正在后台运行的服务组件,这些组件的Service.onStartCommand函数(或者是Service.onStart)已被调用,但是并未调用Service.stopSelf等函数来停止组件,此时,它依旧在后台提供服务,典型的代表有后台播放音乐的服务、正进行邮件推送的服务,等等。
后台服务所在的进程(同时它不是前台进程或可视进程),被称为服务进程。Android系统如果终止这些进程并回收内存空间,可能也会直接影响用户体验,比如用户正在听的歌中断了,新邮件的推送延迟了,等等。因此,只要资源允许,系统就不会回收此类进程。
前台进程、可视进程、服务进程在Android中可以归为一大类,本书称为“体验型”进程。为了保证用户体验,确保用户交互不被中断,只要资源允许,Android都不会回收这类进程。
而其余两个优先级的进程,运行在其中的组件都不会对用户体验造成直接的影响。后台进程中,寄宿着一些非交互态的界面组件,统称为后台界面组件。这些组件对象既不在前台与用户交互,也不在用户可视范围内。在当前状态下,用户感受不到它们的存在。
而空进程,指的是其中没有任何运行的界面组件、服务组件或是触发器组件的进程。有时,空进程中立刻会有新的组件对象被构造,为了避免反复构建和销毁进程,Android系统会暂缓对它们的回收。
这两类进程可以被统称为“性能型”进程,Android为了提升全局性能(性能是间接影响用户体验的因素),会在阈值内维持一定数量的此类进程。
[1]参考SDK文档:http://androidappdocs.appspot.com/guide/topics/fundamentals.html#proclife。
[2]前台服务组件从Android 2.0(SDK 5)开始支持。