Chinaunix首页 | 论坛 | 博客
  • 博客访问: 734655
  • 博文数量: 109
  • 博客积分: 1751
  • 博客等级: 上尉
  • 技术积分: 1816
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-31 22:37
文章分类

全部博文(109)

文章存档

2014年(9)

2013年(21)

2012年(48)

2011年(31)

分类: LINUX

2012-11-20 16:58:14

一 简介:

       android应用程序和windows程序一样,都是基于消息驱动的。如果想要了解android系统的消息处理机制,理解Thread、Looper和Handler三个对象必不可少。Android系统中Looper负责管理线程的消息队列和消息循环,即接受线程中的Message并分发、回调处理消息的函数。对于开发者来说,Looper本身可能不太重要,毕竟这个是android系统自身在管理,然而Handler就不一样啦!我们知道在windows程序开发中,通过HWND的sendMssage函数发送特定的Message(系统或者自定义),并在HWND所属的界面类中通过PreTranslateMessage、onMessage等函数进行处理,而在android系统是要通过Handler来实现这一功能。Handler可看做是Looper的一个接口,必须依附于特定的Looper存在,开发者通过sendMessage/sendEmptyMessage/sendMessageAtTime等函数向关联Looper发送消息,在Handler的handleMessage中处理这些消息(需要用户进行重写)。与windows程序开发不同的是,Handler消息的发送与处理并不一定实在界面相关的类中完成,比较灵活!

二 Looper介绍
       Looper类管理线程的消息队列和消息循环,具体来说是为一个线程开启一个消息循环,Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。而一个Looper对象可以对应多个线程,比如主线程的mainLooper,供主线程和所属子线程共同使用。
       创建Handler时会与其被定义时所在线程的Looper绑定,比如,在主线程中定义,其是与主线程的Looper绑定:
       mainHandler = new Handler() 等价于new Handler(Looper.myLooper()).
      注:Looper.myLooper():Return the Looper object associated with the current thread 获取当前线程的looper对象。还有一个类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。

三、Thread中设置自身的Looper
       Android系统的消息队列和消息循环都是针对具体线程的,Thread可以有(也可以没有)自己的Looper,即该线程自身可以维护一个Message队列和消息循环,非主线程如果没有设置自己的Looper,就和主线程共享一个消息队列和消息循环(主线程一定关联Looper,在应用程序启动时由系统创建)。特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。如果想让非主线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。如下例所示:

  1. class LooperThread extends Thread {  
  2.      public Handler mHandler;  
  3.      public void run() {  
  4.          Looper.prepare();  
  5.          mHandler = new Handler() {  
  6.              public void handleMessage(Message msg) {  
  7.                  // process incoming messages here  
  8.              }  
  9.          };  
  10.          Looper.loop();  
  11.      }  
  12.  }  
      这样你的线程就具有了消息处理机制了,在Handler中进行消息处理。上面的代码如果没有设置Looper,直接在线程中new Handler,系统会抛出如下异常:
            E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
            E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
      即Handler必须依赖于特定的Looper。Looper.loop函数会使run函数停留在调用处,直到主动调用线程终止函数或者Looper对象的quit函数才能退出。

      一个 Activity中可以创建多个工作线程或者其他的组件,如果这些线程或者组件把他们的消息放入Activity的主线程消息队列,那么该消息就会在主线程中处理了。因为主线程一般负责界面的更新操作,并且Android系统中的weget不是线程安全的,所以这种方式可以很好的实现Android界面更新。在Android系统中这种方式有着广泛的运用。如上面介绍,其它非主线程通过Handle对象(Handler对象以主线程的Looper创建),那么调用Handler的sendMessage等接口,将会把消息放入队列都将是放入主线程的消息队列。并且将会在Handler主线程中调用该handler 的handleMessage接口来处理消息。

阅读(779) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~