android消息处理——Thread、Looper、Handler

一 简介:

       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()进入消息循环。如下例所示:

 class LooperThread extends Thread {
      public Handler mHandler;
      public void run() {
          Looper.prepare();
          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };
          Looper.loop();
      }
  }
      这样你的线程就具有了消息处理机制了,在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接口来处理消息。

      更详细的内容参考:http://blog.csdn.net/dywe_ddm/article/details/5930948、http://www.android123.com.cn/androidkaifa/422.html、http://hi.baidu.com/donghaozheng/blog/item/d963d7333e39844dac4b5f1b.html


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值