`
bcyy
  • 浏览: 1818247 次
文章分类
社区版块
存档分类
最新评论

Android 进程和线程(一)

 
阅读更多
当一个应用程序组件启动并且应用还没有运行任何其他组件时,Android系统会给应用程序启动一个新的带有单一执行线程的Linux进程。默认情况下,同一应用程序的所有组件都运行在相同的进程和线程(被叫做“主”线程)中。如果应用程序组件启动,并且针对这个应用的进程已经存在(因为应用程序中的其他组件的存在),那么这个组件就会在应用对应的进程中被启动,并且使用相同的执行线程。但是你能够安排应用程序中不同的组件运行在各自的进程中,并且你能够给任意进程创建额外的线程。

本文档讨论Android应用程序中进程和线程是怎样工作的。

进程

默认情况下,同一应用程序的所有组件都运行在同一进程中,并且大多数应用程序都不应该改变这种模式。但是,如果你发现需要控制某个组件属于哪个进程时,你能够在清单文件中做这件事情。

对于每种类型组件的清单入口元素---<activity>、<service>、<receiver>、和<provider>,都支持一个android:process属性,它能够指定组件应用应该运行在哪个进程中。你能够设置这个属性,以便每个组件运行在它自己的进程中,或者让某些组件共享一个进程,而其他的不共享。你也能够设置android:process属性以便不同应用程序的组件运行在同一个进程中---提供应用程序共享的相同的Linux用户ID和相同的证书签名。

<application>元素也支持一个android:process属性,用于设置应用程序所有组件的默认值。

当系统内存低并且启动进程要求立即服务用户的时候,Android系统可以决定在某个时点关掉一个进程,运行在这个进程中的应用程序组件也会因进程被杀死而销毁。当用户再次要求被杀死的进程为其工作时,这对这些组件的进程会再次被启动。

当要决定要杀死哪个进程时,Android系统会权衡它们对用户的重要性。例如,跟持有可见Activity的进程相比,系统更容易关掉持有不在屏幕上显示的Activity的进程。因此,要决定是否终止一个进程,依赖与那个进程中组件的运行状态。以下讨论用于决定终止哪个进程的规则。

进程的生命周期

Android系统会尝试尽可能长维护一个应用程序进程,但是最终为了给新的或更重要的进程回收内存时要删除旧的进程。要决定哪个进程要保留,哪个进程要杀死,系统会基于进程中运行的组件和这些组件的状态把每个进程放到一个“重要性层次表中,带有最低重要性的进程会首先被销毁,然后是下一个最低重要的,依次类推,直到系统回收到了需要的资源。

在重要性层次中有五个级别。以下按照重要性的顺序列出了不同类型进行的表现(第一种类型进程是最终的并且在最后被杀死):

1.前台进程

前台进程是用户当前作业必须的一个进程。一个进程满足以下任何条件都被认为是前台进程:

A.进程持有一个正在跟用户交互的Activity对象(Activity的onResume()方法已经被调用);

B.进程持有一个正在跟用户交互的Activity绑定的Service对象;

C.进程持有一个正在前台运行的Service对象---这个Service已经调用了startForeground()方法;

D.进程持有正在执行生命周期的一个回调方法的Service对象(onCreate()、onStart()、或onDestroy());

E.进程持有一个正在执行onReceive()方法的BroadcastReceiver对象。

一般情况,在给定的时间只有很少的前台进程存在。杀死这些进程只是要采取的最后手段---如果内存很低导致它们不能继续运行。在这个时点,设备已到达内存的饱和状态,因此必须杀死一些前台进程来保持对用户界面的响应。

2.可见进程

可见进程是指没有任何前台组件的一个进程,但是仍然能够影响用户在屏幕上看到的内容。如果满足下列条件之一,进程被认为是可见的:

A.进程持有一个不在前台的Activity,但是这个Activity依然对用户可见(它的onPause()方法已经被调用)。这是可能发生的,如果前台程序启动一个对话框,允许在这个对话框的后面看到之前的那个Activity。

B.进程持有一个绑定到一个可见(或前台)的Activity的Service。

一个可见进程被认为是非常重要的,并且只有在要求保留所有前台正在运行的进程时才可以杀死这种类型的进程。

3.服务进程

服务进程是指用startService()方法启动的正在运行的一个服务的进程,并且这个进程没有被归入上面介绍的两个分类。虽然服务进程不直接跟用户看到的任何东西捆绑,但是,通常他们都在做用户关心的事情(如在后台播放音乐,或下载网络上的数据),除非用来保留跟它们一起的所有前台和可见进程的内存不足,否则系统会一直保留它们。

4.后台进程

后台进程是指持有一个用户当前不可见的Activity的进程(这个Activity的onStop()方法已经被调用)。这些进程不会直接影响用户体验,并且为了给前台、可见、或服务进程回收内存,系统能够在任何时候杀死它们。通常会有很多后台进程在运行,因此它们被保留在一个LRU(Least recently used)列表中以确保用户最近看到的那个带有Activity的进程最后被杀死。如果一个Activity正确的实现了它的生命周期方法,并且保存了当前的状态,那么杀死它的进程将不会影响用户的视觉体验,因为返回到这个Activity是,这个Activity会恢复所有的可见状态。

5.空进程

空进程是指不持有任何活动的应用程序组件的一个进程。保留这种进程存活的唯一原因是为了缓存的目的,以便提高需要在其中运行的组件的下次启动时间。为了平衡进程缓存和基础内核缓存之间的整体系统资源,系统会经常杀死这些进程。

Android能基于进程中当前活跃的组件的重要性来安排一个进程的级别(选择其中优先级最高的作为进程的级别)。如,如果一个进程持有一个Service和一个可见的Activity,那么这个进程就会被安排到可见进程而不是服务进程。

另外,一个进程的排名可能因为其他进程的依赖而上升---一个正在服务另一个进程的进程,它的排名不会比它所服务的那个进程低。例如,进程A中的一个内容提供器服务与客户端进程B,或者进程A中的一个服务绑定了进程B中的一个组件,那么进程A始终被认为比进程B重要。

因为运行服务的进程的排名要比带有后台Activity的进程高,因此启动一个长时操作的Activity时可能为此操作启动一个服务,而不是简单的创建一个工作线程---尤其是这操作很可能长久用于这个Activity时。例如,给一个网站上传图片的Activity就应该启动一个执行上传功能的服务,以便上传能够在后台持续工作,即使用户离开了这个Activity。同样的原因,Broadcast Receiver应该采用服务而不是简单的放在一个耗费操作时间的线程中。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics