首页 > 代码库 > Android 进程与线程管理

Android 进程与线程管理

一、简介

  进程(Process)是程序的一个运行的实例,以区别“程序”这一静态的概念。线程(Thread)是CPU调用的基本单位。

二、进程的组成部分

  在Android中的四大组件是进程组成的一部分,Android App在启动时,创建App进程,以及主线程(UI线程)和两个Binder线程。创建一个新工程,在工程中创建一个Activity、Service、BroadcastReceiver,分别在onCreate(...)和onReceiver(...)方法Debug 断点调试。查看Activity、Service、BroadcastReceiver组件创建及启动过程。

  启动应用创建App进程:

技术分享

 

 

  Activity启动:

技术分享

  Service启动:

技术分享

  BroadcastReceiver启动:

技术分享

 

  由调试可以看到Activity、Service、BroadcastReceiver组件都是在主线程中创建的,其创建过程基本上一致。所以,Service、BroadcastReceiver执行耗时操作时,要在子线程中执行。

三、Runnable、Message、MessageQueue、Looper、Handler

  在Android开发中,使用消息队列(message)完成线程间通信。而使用消息队列的线程就是消息循环(message looper)。消息循环不断的检查消息队列,是否有新消息。消息循环是由一个线程和一个looper组成;looper对象管理着线程的消息队列。

 

  Android的主线程也是一个消息循环,也具有一个Looper,主线程所有的任务都是由looper完成。消息循环是由一个线程和一个looper组成,looper对象管理着线程的消息队列;因此,looper不断的从消息队列中抓取消息,然后完成消息指定的任务。

 

  PS: 线程默认情况下,是没有消息循环(Looper)的,在Android中,只有主线程默认就是Looper(消息循环)。在新创建的线程中,使用Looper,要先创建一个Looper才行。

 

  从下面图中了解一下Runnable、Message、MessageQueue、Looper、Handler含义:

技术分享

 

                (此图来自于其它书籍资料)

  将这此含义揉合在一起就是一个消息从发出到执行的整个过程:

技术分享

              (此图来自于其它书籍资料)

  从上面这两个图中,我们可以了解到:

  1. Runnable和Message压入到MessageQueue中,形成一个消息集合。

  2. Looper在不断的循环,不停的在做某一件事,比如:上图中Looper在不停的从MessageQueue中拿出Item,再传递给Handler执行。

  3. Handler在不断的去做某一具体的事情,比如:Handler收到一个消息,去解析一个后台返回的数据,再将其更新到UI上。

  从上面来看,Handler和Thread从表像上看确实没有直接的关系,但是因为:

  1.  每个Thread只能对应一个Looper;

  2. 每个Looper只能对应一个MessageQueue;

  3. 每个MessageQueue有N个Message;

  4. 每个Message最多指定一个Handler来处理;

  由此,可以推出Thread和Handler是一对多的关系。而Handler有两方面作用:

  1. 处理Message,作为Message处理者。

  2. 负责将Message压入MessageQueue中。

 

四、Message与Handler

 

  Message与Handler是成对出现的,Message是消息,而Handler是消息要完成任务的对象。

 

  消息是Message的一个实例,在实现一个消息时,要同时实现Message类的一些实例变量,

 

    • what: 用户定义的Int类型消息代码,用来描述消息。
    • obj: 随消息一起发送的用户指定的对象,即消息传递的数据。
    • target:完成消息指定任务的目标,即用来完成消息指定任务的对象。

 

  Handler是完成消息或消息指定任务的对象,Handler不仅是完成消息的目标或对象,也是创建和发布消息(Message)的接口。技术分享

 

                 (图来源于Android权威指南)

 

 

 

  • Looper拥有message的消息队列,所以,message必须在Looper上发布或读取。
  • 一个Handler仅一个Looper相关联,一个Message也仅与一个目标Handler(message目标)相关联。而Looper拥有消息的整个队列。

 

在看看下面这个图,

 

技术分享

 

              (图来源于Android权威指南)

 

从上面这个图中,可以看出,有多个Handler与一个Looper相关联,这说明一个Handler的message与另一个Handler的message放于同一个消息队列。

 

 五、Handler使用

 

  1. 使用Handler.obtainMessage(...)方法会从公共循环消息队列中,获取message。

 

  2. 使用Handler.sendToTarget()方法,会方法消息发送给与message相关联的Handler。而Handler会将message放于Looper的消息队列尾部。

 

  3. Looper在消息队列中,获取到特定的消息后,将其发送给消息目标(与之相关联的Handler)去处理。消息一般在Handler(消息目标)的handlerMessage(...)实现方法处理消息指定要完成的任务。一般,要继承Handler基类,覆盖handlerMessage()方法。

 

 六、传递Handler

 

  Handler类的一个实例,可以作为函数参数,传递给其它子线程。

 

  主线程拥有一个Handler和Looper消息循环,在线程中,主线程上创建一个Handler,会自动与主线程的Looper相关联。将主线程创建的Handler传递给另一个子线程,传递出去的Handler始终会与创建它的线程的Looper保持联系。因此,任何已传出的Handler负责处理的消息,都将在主线程的消息队列中处理。

 

  那么,就可以通过这种方式,在子线程中,去更新主线程的事件,数据,或者UI。

 

七、在新线程中,创建Looper(消息循环)

 

  在主线程中不用创建Looper是因为App启动时,创建主线程中默认创建了Looper,并且一个线程中,只能有一个Looper。存在多个系统会报错。

 

  Looper为什么不会堵塞主线程,提示ANR(application not responding)?

 

  因为,主线程中的Activity和所有事件都是通过Looper执行的。Looper有一个消息队列,在不断的接收事件消息和执行事件。此中的堵塞是指Looper循环不被堵塞,而非Looper堵塞线程。

 

Android 进程与线程管理