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