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

一、介绍三个相关的类

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

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

  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两种典型的使用方式!

  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: {

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对象发送出去。

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

Android中的Message机制的更多相关文章

  1. 浅析Android中的消息机制(转)

    原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class ...

  2. 浅析Android中的消息机制(转)

    在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...

  3. 浅析Android中的消息机制-解决:Only the original thread that created a view hierarchy can touch its views.

    在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...

  4. 浅析Android中的消息机制

    在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...

  5. 重温Android中的消息机制

    引入: 提到Android中的消息机制,大家应该都不陌生,我们在开发中不可避免的要和它打交道.从我们开发的角度来看,Handler是Android消息机制的上层接口.我们在平时的开发中只需要和Hand ...

  6. 谈谈对Android中的消息机制的理解

    Android中的消息机制主要由Handler.MessageQueue.Looper三个类组成,他们的主要作用是 Handler负责发送.处理Message MessageQueue负责维护Mess ...

  7. Android中的消息机制

    在分析Android消息机制之前.我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...

  8. Android中的Parcel机制 实现Bundle传递对象

    Android中的Parcel机制    实现了Bundle传递对象    使用Bundle传递对象,首先要将其序列化,但是,在Android中要使用这种传递对象的方式需要用到Android Parc ...

  9. 探索Android中的Parcel机制(上)

    一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化……,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态 ...

随机推荐

  1. Git之(六)标签管理

    发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本.将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来.所以,标签也是版本库的一个快照 ...

  2. linux网络编程之一-----多播(组播)编程

    什么是多播 组播(Multicast)是网络一种点对多(one to many)的通信方式,通过报文复制完成网络中一台server对应多台接收者的高效数据传 送.对其形象的比喻就是类似于广播电台和电视 ...

  3. KVO and Swift

    不像Objective-c中的类,Swift类对于KVO并没有原生的支持,不过你可以在类型安全的前提下使用属性观察者轻松的完成相同的目标. 不管如何,从NSObject类派生出的类是支持KVO的,如果 ...

  4. 干货:MySQL 索引原理及慢查询优化

    MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修 ...

  5. Dynamics CRM2016 Web API之通过实体的primary key查询记录

    CRM2016启用了webapi 而弃用了odata,作为码农的我们又开始学习新东西了. 下面是一段简单的查询代码,通过systemuser的primary key来查询一条记录 Web API查询方 ...

  6. EBS业务学习之应付INVOICE类型

    INVOICE类型 类      型 描           述 标准INVOICE 是指由于采购货物或接受劳务,从供应商处取得的INVOICE (标准INVOICE,既可以和订单匹配,也可以不匹配) ...

  7. 设置 NSZombieEnabled 定位 EXC_BAD_ACCESS 错误

    我们做 iOS 程序开发时经常用遇到 EXC_BAD_ACCESS 错误导致 Crash,出现这种错误时一般 Xcode 不会给我们太多的信息来定位错误来源,只是在应用 Delegate 上留下像 T ...

  8. mysql进阶(二十八)MySQL GRANT REVOKE用法

    mysql进阶(二十八)MySQL GRANT REVOKE用法   MySQL的权限系统围绕着两个概念: 认证->确定用户是否允许连接数据库服务器: 授权->确定用户是否拥有足够的权限执 ...

  9. javascript之内置函数

    1.常规函数 (1)alert函数:显示一个警告对话框,包括一个OK按钮. (2)confirm函数:显示一个确认对话框,包括OK.Cancel按钮. (3)escape函数:将字符转换成Unicod ...

  10. 重载Cocos2D生存期的方法

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交 ...