Android
系统会尽可能时间长的来维持一个程序的进程,但当系统资源紧张的时候,系统终究会为一些新的或者更重要的进程杀死一些旧的进程来释放内存。系统主要是根据进程中组件的运行状态,来决定每一个进程的重要性,从而决定哪个进程需要杀死,哪个进程需要保持。最不重要的进程最容易先被杀死,其次最不重要的进程会被杀死,以此往复,直到系统恢复了需要的资源。
既然系统主要根据进程的重要性来决定一个进程的存亡,下面我们就将介绍根据重要性分类的五种不同进程(重要性 由高到低)。
1.foreground process,前台进程
所谓前台进程就是指用户完成当前工作而需要的进程。判断条件如下(满足其一即可):
- 进程中的某个 Activity 正在与用户进行交互( Activity 的 onResume() 方法被调用)
- 绑定到与当前用户正在交互的 activity 的 Service 所在的进程
- 进程中的某个 Service 正运行在前台,即这个 service 的 startForeground() 方法被调用
- 进程中的某个 Service 正在执行生命周期回调方法(比如, onCreate() , onStart() ,或者 onDeatroy() )
- 进程中的 BroadcastReceiver 正在执行 onReceive() 方法。
一般来说的话,在某特定时刻,也仅会有为数不多的几个前台进程。这些前台进程的重要性最高,当系统内存低到很低,以致不能继续运行这些所有的进程的话,系统将会杀死这些进程。这种情况下,一般是指系统已经到了一个极限边缘了,所以为了让 UI 继续有反应的话,系统不得不杀死一些前台进程。
2.可视进程-visible process
可视进程是指没有前台运行的组件,但仍然会对用户在屏幕看到的内容造成影响的进程。满足下面条件的进程都可以算作可视进程:
- 进程运行的 Activity 不在前台,但仍然是可见的(调用了 onPause() 方法)。这种情况可能是这样的,正在前台运行的 Activity 启动了一个对话框,这个对话框悬浮在这个 activity 之上,但仍有部分可见。
- 进程中的 Service 绑定到了一个可视(或前台)的 activity (该 activity 已调用了 onPause() 方法)。
可视进程也是有着极高重要性的进程,只有在系统为了保持前台进程运行而不得不杀死可视进程的时候,才会杀死可视进程。
3.服务进程-service process
所谓的服务进程,就是指除了上面两种进程外,如果一个进程已经通过 startService() 方法启动了一个 service 的进程。虽然这种 service 进程跟用户的看到的内容不相关,但它们所做的工作也是用户关心的(比如在后台播放音乐或者正在下载互联网上的资源),系统会一直保持服务进程,除非系统为了前台进程和可视进程的运行,而不得不杀死服务进程。
4.后台进程-background process
后台进程是指进程中的 activity 当前对用户来说不可见(这个 activity 调用了 onStop() 方法)。后台进程不会对用户的体验造成任何影响,并且系统可以在前台进程、可视进程、服务继承需要内存资源的时候会杀死后台进程。通常会有很多后台进程运行,并且这些后台进程保存在一个最近使用列表中,这样做的好处就是保证用户最近看到的进程最后被杀死。如果一个 activity 已经正确的实现了生命周期方法,并且保存了当前的状态,那么系统杀死这些后台进程对用户的可视效果来说的话,没有任何影响,因为当用户返回回来的时候,这个 activity 已经保存了所有的可视状态。
5.空进程-empty process
一个空进程没有任何运行的程序组件。系统保持空进程存在的唯一原因就是为了 缓存方面的考虑,这样做主要是为了提高组件的启动时间。系统经常会杀死这些空进程来保持整个系统资源和内核缓存之间的平衡。
Android 根据进程中运行的最重要的组件进行划分进程的重要性,比如说,如果一个进程中即有一个可视的 activity ,又有一个 service ,那么这个进程应该属于可视进程而不是服务进程。
另外,一个进程的重要性等级可能会因为依赖于该进程的其他进程而提高——一个服务于其他进程的重要性不会低于被服务的进程。比如说,进程 A 中的一个 content provider 正在为进程 B 中的客户服务,或者进程 A 中的一个 service 被绑定到了进程 B 中的一个组件,那么进程 A 的重要性至少会被认为是和 B 的重要性是一样的。
因为 一个正在运行的服务所在的进程的重要性高于一个处于后台的activity 所在的进程,所以根据这一点,如果一个 activity如果要执行需要长时间运行的操作的话,这个activity 最好为该操作启动一个新的服务,而不是仅仅创建一个工作线程,尤其是当这个工作线程运行的时间可能比该 activity 的运行时间还长的时候。比如说,如果一个 activity 要往一个网站上上传一张图片的话,这个 activity 就应该启动一个服务来完成这个上传操作,这要做的好处就是即使用户离开了当前的这个 activity ,上传服务还会继续进行。使用一个服务保证一个进程至少还有服务进程这个优先级,而不用担心 activity 会发生什么情况。这也正是为什么广播接收者应该使用服务而不是把耗时的操作放在一个线程中的原因。
参考文档:http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html
既然系统主要根据进程的重要性来决定一个进程的存亡,下面我们就将介绍根据重要性分类的五种不同进程(重要性 由高到低)。
1.foreground process,前台进程
所谓前台进程就是指用户完成当前工作而需要的进程。判断条件如下(满足其一即可):
- 进程中的某个 Activity 正在与用户进行交互( Activity 的 onResume() 方法被调用)
- 绑定到与当前用户正在交互的 activity 的 Service 所在的进程
- 进程中的某个 Service 正运行在前台,即这个 service 的 startForeground() 方法被调用
- 进程中的某个 Service 正在执行生命周期回调方法(比如, onCreate() , onStart() ,或者 onDeatroy() )
- 进程中的 BroadcastReceiver 正在执行 onReceive() 方法。
一般来说的话,在某特定时刻,也仅会有为数不多的几个前台进程。这些前台进程的重要性最高,当系统内存低到很低,以致不能继续运行这些所有的进程的话,系统将会杀死这些进程。这种情况下,一般是指系统已经到了一个极限边缘了,所以为了让 UI 继续有反应的话,系统不得不杀死一些前台进程。
2.可视进程-visible process
可视进程是指没有前台运行的组件,但仍然会对用户在屏幕看到的内容造成影响的进程。满足下面条件的进程都可以算作可视进程:
- 进程运行的 Activity 不在前台,但仍然是可见的(调用了 onPause() 方法)。这种情况可能是这样的,正在前台运行的 Activity 启动了一个对话框,这个对话框悬浮在这个 activity 之上,但仍有部分可见。
- 进程中的 Service 绑定到了一个可视(或前台)的 activity (该 activity 已调用了 onPause() 方法)。
可视进程也是有着极高重要性的进程,只有在系统为了保持前台进程运行而不得不杀死可视进程的时候,才会杀死可视进程。
3.服务进程-service process
所谓的服务进程,就是指除了上面两种进程外,如果一个进程已经通过 startService() 方法启动了一个 service 的进程。虽然这种 service 进程跟用户的看到的内容不相关,但它们所做的工作也是用户关心的(比如在后台播放音乐或者正在下载互联网上的资源),系统会一直保持服务进程,除非系统为了前台进程和可视进程的运行,而不得不杀死服务进程。
4.后台进程-background process
后台进程是指进程中的 activity 当前对用户来说不可见(这个 activity 调用了 onStop() 方法)。后台进程不会对用户的体验造成任何影响,并且系统可以在前台进程、可视进程、服务继承需要内存资源的时候会杀死后台进程。通常会有很多后台进程运行,并且这些后台进程保存在一个最近使用列表中,这样做的好处就是保证用户最近看到的进程最后被杀死。如果一个 activity 已经正确的实现了生命周期方法,并且保存了当前的状态,那么系统杀死这些后台进程对用户的可视效果来说的话,没有任何影响,因为当用户返回回来的时候,这个 activity 已经保存了所有的可视状态。
5.空进程-empty process
一个空进程没有任何运行的程序组件。系统保持空进程存在的唯一原因就是为了 缓存方面的考虑,这样做主要是为了提高组件的启动时间。系统经常会杀死这些空进程来保持整个系统资源和内核缓存之间的平衡。
Android 根据进程中运行的最重要的组件进行划分进程的重要性,比如说,如果一个进程中即有一个可视的 activity ,又有一个 service ,那么这个进程应该属于可视进程而不是服务进程。
另外,一个进程的重要性等级可能会因为依赖于该进程的其他进程而提高——一个服务于其他进程的重要性不会低于被服务的进程。比如说,进程 A 中的一个 content provider 正在为进程 B 中的客户服务,或者进程 A 中的一个 service 被绑定到了进程 B 中的一个组件,那么进程 A 的重要性至少会被认为是和 B 的重要性是一样的。
因为 一个正在运行的服务所在的进程的重要性高于一个处于后台的activity 所在的进程,所以根据这一点,如果一个 activity如果要执行需要长时间运行的操作的话,这个activity 最好为该操作启动一个新的服务,而不是仅仅创建一个工作线程,尤其是当这个工作线程运行的时间可能比该 activity 的运行时间还长的时候。比如说,如果一个 activity 要往一个网站上上传一张图片的话,这个 activity 就应该启动一个服务来完成这个上传操作,这要做的好处就是即使用户离开了当前的这个 activity ,上传服务还会继续进行。使用一个服务保证一个进程至少还有服务进程这个优先级,而不用担心 activity 会发生什么情况。这也正是为什么广播接收者应该使用服务而不是把耗时的操作放在一个线程中的原因。
参考文档:http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html
下一篇将继续介绍android线程的相关知识。