Android的Handler消息传递机制

本文转载自http://blog.csdn.net/dadoneo/article/details/7667726

对于Android的Message机制主要涉及到三个主要的类,分别是Handler、Message、Looper;首先对每个类做一个简单介绍;然后再介绍Android的Message机制是如何实现的,最后给了一个示例。


一、关于Handler、Message和Looper

1、 Handler主要有两个用途:首先是可以定时处理或者分发消息,其次是可以添加一个执行的行为在其它线程中执行

对于Handler中的方法,可以选择你关心的操作去覆盖它,处理具体的业务操作,常见的就是对消息的处理可以覆盖public void handleMessage(parameters)方法,可以根据参数选择对此消息是否需要做出处理,这个和具体的参数有关。例如下代码:

  1. Handler mHandler = new Handler() {  
  2. @Override public void handleMessage(Message msg) { //覆盖handleMessage方法
  3.        switch (msg.what) { //根据收到消息的what类型进行处理
  4.             case BUMP_MSG:  
  5.                 Log.v("handler""Handler===="+msg.arg1); //打印收到的消息
  6.                 break;  
  7.            default:  
  8.                 super.handleMessage(msg); //将不关心的消息传给父类,避免丢失消息
  9.                break;  
  10.         }  
  11.     }  
  12. }; 

2、 消息 android.os.Message

android.os.Message 是定义一个 Messge 包含必要的描述和属性数据,并且此对象可以被发送给 android.os.Handler 处理。属性字段:arg1、arg2、what、obj、replyTo 等;其中 arg1和arg2 是用来存放整型数据的;what 是用来保存消息标示的;obj 是 Object 类型的任意对象;replyTo 是消息管理器,会关联到一个 handler,handler 就是处理其中的消息。通常对 Message 对象不是直接new出来的,只要调用 handler 中的 obtainMessage() 方法来直接获得 Message 对象。

3、 Looper类主要用于一个线程循环获取消息队列中的消息。

Looper 的作用主要是负责管理消息队列,负责消息的出列和入列操作。


二、Android的Message机制是如何实现?

1、为什么要使用 Message 机制主要是为了保证线程之间操作安全,同时不需要关心具体的消息接收者,使消息本身和线程剥离开,这样就可以方便的实现定时、异步等操作。

2、Message机制原理示意图:

                            Activity     <--------------->  EHandler  <----->   Looper   <------>   MessageQueue     

                   IntentReceiver  <-------------->  EHandler  <------>   Looper   <------>   MessageQueue       

                                                                                            图 1

3、 如何实现?(具体描述上图的消息流的过程)

实现 Message 机制需要 Handler、Message、Loope 三个之间的互相作用来实现;当线程A需要发消息给线程B的时候,线程B要用自己的 Looper 实例化 Handler 类,就是构造handler对象时,把当前线程的 Looper 传给Handler构造函数,handler 本身会保存对 Looper 的引用,handler 构造好以后,就可以用handler 的 obtainMessage 方法实例化Message对象,只要把要传的数据给 Handler,Handler 就会构造 Message 对象,并且把 Message 对象添加到消息队列里面。然后就可以调用 handler 的 sendMessage 方法把 Message 对象发送出去,Looper 就把消息放到消息队列中;最后当 Looper 知道消息队列不为空时候,就会循环的从消息队列中取消息,取出消息就会调用刚才实例化好的 Handler 对象的 handleMessage 方法取处理消息,整个 Message 过程就是这样(如图1所示)。


三、下面介绍一个关于Message机制的简单的示例,具体的代码如下:

1、 下面是一个新创建线程发送消息的示例

handler 本身不仅可以发送消息,还可以用 post 的方式添加一个实现 Runnable 接口的匿名对象到消息队列中,在目标收到消息后就可以通过回调的方式在自己的线程中执行run的方法体,这就是 handler 两种典型的使用方式!

<span style="font-family:Courier New;font-size:14px;">class NoLooperThread extends Thread {  
    private EventHandler mNoLooperThreadHandler;  
    public void run() {  
        Looper   myLooper, mainLooper;  
        myLooper= Looper.myLooper();   //获得自己的Looper  
            mainLooper= Looper.getMainLooper();    //获得自己的main的looper  
            String obj;  
            if (myLooper == null) {  
                    mNoLooperThreadHandler = new EventHandler(mainLooper);  
                    obj= "NoLooperThread has no looper andhandleMessage function executed in main thread!";  
            }else  
            {  
                    mNoLooperThreadHandler = new EventHandler(myLooper);  
                    obj= "This is from NoLooperThread self andhandleMessage function executed in NoLooperThread!";  
            }  
            mNoLooperThreadHandler.removeMessages(0);    //清空消息队列  
            if (false == postRunnable) {  
                    Message m = mNoLooperThreadHandler.obtainMessage(2, 1, 1, obj);    //生成消息对象  
                    mNoLooperThreadHandler.sendMessage(m);   //发送消息  
                    Log.e(sTag, "NoLooperThread id:" + this.getId());  
            }else {  
                    mNoLooperThreadHandler.post(new Runnable() {    //添加一个Runnable接口的实现到消息队列,此Runnable接口的实现不在此线程中执行,会在接收的线程中执行。  
                        public void run() {  
                            tv.setText("update UI through handler post runnalbe mechanism!");  
                            noLooerThread.stop();  
                        }  
                    });  
            }  
}  </span>

2、下面是一个定时循环发消息的示例,详细的解释请参考代码注释,代码如下

<span style="font-family:Courier New;font-size:14px;">Handler handler = new Handler() {    //创建处理对象handler

    publicvoid handleMessage(Message msg) {   

        switch (msg.what){

                      caseMES: {
                                   final int N = mCallbacks.beginBroadcast();    //Copy一份回调list,并且标记一个状态
                                   for (int i = 0; i <N; i++) {
                                        try {
                                                  mCallbacks.getBroadcastItem(i).getValue(mMediaPlayer01.getCurrentPosition());   //遍历所有回调接口
                                            }  catch (Exception e) {
                                                         e.printStackTrace();
                                                    }
                                    }

                                    mCallbacks.finishBroadcast();     //完成后状态复位
                                    sendMessageDelayed(obtainMessage(MES),1 * 1000);
                                }
                                break;

                          default:
                                    super.handleMessage(msg);
                             }

         }
 };</span>
NOTE:整个hadleMessage方法相当一个嵌套的循环


、总结:

所谓的消息机制其实很简单,实现这种机制需要只需要四步:

     1、实例化Looper(因为实例化 Handler 时需要一个looper);

     2、实例化Handler,这里需要覆盖 handleMessage 方法,处理收到的消息;

     3、 实例化Message对象调用已经实例化好的handler对象的obtainMessage方法,把数据传给obtainMessage方法,obtainMessage方法就会实例化一个Message对象。(这里也可以发送实现Runnable接口的对象);

     4、调用 Handler 的 sendMessage 方法把实例化好的Message对象发送出去。

对每个线程过程都是一样的,只要按照上面的四个步骤来就可以发送和接收消息了。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值