Android的Message机制

但使书种多,会有岁稔时。这篇文章主要讲述Android的Message机制相关的知识,希望能为你提供帮助。
对于android的Message机制主要涉及到三个主要的类,分别是Handler、Message、Looper;首先对每个类做一个简单介绍;然后再介绍所谓的Android的Message机制是如何实现的,最后给了一个示例。
 
一、介绍三个相关的类
1、 Handler主要有两个用途:首先是可以定时处理或者分发消息,其次是可以添加一个执行的行为在其它线程中执行,
对于Handler中的方法,可以选择你关心的操作去覆盖它,处理具体的业务操作,常见的就是对消息的处理可以覆盖public voidhandleMessage(参数)方法,可以根据参数选择对此消息是否需要做出处理,这个和具体的参数有关。例如下代码:
 
[java]  view plain  copy     print?

  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、Looper三个之间的互相作用来实现;当线程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两种典型的使用方式!
 
[java]  view plain  copy     print?
  1. class  NoLooperThread  extends  Thread  {   
  2.         private  EventHandler  mNoLooperThreadHandler;    
  3.         public  void  run()  {   
  4.                 Looper      myLooper,  mainLooper;    
  5.                 myLooper=  Looper.myLooper();       //获得自己的Looper   
  6.                         mainLooper=  Looper.getMainLooper();         //获得自己的main的looper   
  7.                         String  obj;    
  8.                         if  (myLooper  ==  null)  {   
  9.                                         mNoLooperThreadHandler  =  new  EventHandler(mainLooper);    
  10.                                         obj=  "NoLooperThread  has  no  looper  andhandleMessage  function  executed  in  main  thread!";    
  11.                         }else   
  12.                         {   
  13.                                         mNoLooperThreadHandler  =  new  EventHandler(myLooper);    
  14.                                         obj=  "This  is  from  NoLooperThread  self  andhandleMessage  function  executed  in  NoLooperThread!";    
  15.                         }   
  16.                         mNoLooperThreadHandler.removeMessages(0);         //清空消息队列   
  17.                         if  (false  ==  postRunnable)  {   
  18.                                         Message  m  =  mNoLooperThreadHandler.obtainMessage(2,  1,  1,  obj);         //生成消息对象   
  19.                                         mNoLooperThreadHandler.sendMessage(m);       //发送消息   
  20.                                         Log.e(sTag,  "NoLooperThread  id:"  +  this.getId());    
  21.                         }else  {   
  22.                                         mNoLooperThreadHandler.post(new  Runnable()  {        //添加一个Runnable接口的实现到消息队列,此Runnable接口的实现不在此                                                                    线程中执行,会在接收的线程中执行。   
  23.                                                 public  void  run()  {   
  24.                                                         tv.setText("update  UI  through  handler  post  runnalbe  mechanism!");    
  25.                                                         noLooerThread.stop();    
  26.                                                 }   
  27.                                         });    
  28.                         }   
  29. }   



 
 
2、下面是一个定时循环发消息的示例,如下代码:
详细的解释参考代码的注释
Handler  handler  =  new  Handler() {     //创建处理对象handler
                                                                      publicvoid  handleMessage(Message msg) {    
                                                                                              switch  (msg.what) {
                                                                                              caseMES: {
【Android的Message机制】                                                                                                                      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);
                                                                                                                    }
                                                                                            }
                                                                    };
   
NOTE:     整个hadleMessage方法相当一个嵌套的循环
 
四、总结:
所谓的消息机制其实很简单,实现这种机制需要只需要四步:
          1、实例化Looper(因为实例化Handler时需要一个looper);
          2、实例化Handler,这里需要覆盖handleMessage方法,处理收到的消息;
          3、 实例化Message对象,调用已经实例化好的handler对象的obtainMessage方法,把数据传给obtainMessage方法,obtainMessage方法就会实例化一个Message对象。(这里也可以发送实现Runnable接口的对象);
          4、调用Handler的sendMessage方法把实例化好的Message对象发送出去。
对每个线程过程都是一样的,只要按照上面的四个步骤来就可以发送和接收消息了。





    推荐阅读