Android中的Message机制
对于Android的Message机制主要涉及到三个主要的类,分别是Handler、Message、Looper;首先对每个类做一个简单介绍;然后再介绍所谓的Android的Message机制是如何实现的,最后给了一个示例。
一、介绍三个相关的类
1、 Handler主要有两个用途:首先是可以定时处理或者分发消息,其次是可以添加一个执行的行为在其它线程中执行,
对于Handler中的方法,可以选择你关心的操作去覆盖它,处理具体的业务操作,常见的就是对消息的处理可以覆盖public voidhandleMessage(参数)方法,可以根据参数选择对此消息是否需要做出处理,这个和具体的参数有关。例如下代码:
- Handler mHandler = new Handler() {
- @Override public void handleMessage(Message msg) {//覆盖handleMessage方法
- switch (msg.what) {//根据收到的消息的what类型处理
- case BUMP_MSG:
- Log.v("handler", "Handler===="+msg.arg1);//打印收到的消息
- break;
- default:
- super.handleMessage(msg);//这里最好对不需要或者不关心的消息抛给父类,避免丢失消息
- break;
- }
- }
- };
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两种典型的使用方式!
- 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();
- }
- });
- }
- }
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机制的更多相关文章
- 浅析Android中的消息机制(转)
原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class ...
- 浅析Android中的消息机制(转)
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 浅析Android中的消息机制-解决:Only the original thread that created a view hierarchy can touch its views.
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 浅析Android中的消息机制
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 重温Android中的消息机制
引入: 提到Android中的消息机制,大家应该都不陌生,我们在开发中不可避免的要和它打交道.从我们开发的角度来看,Handler是Android消息机制的上层接口.我们在平时的开发中只需要和Hand ...
- 谈谈对Android中的消息机制的理解
Android中的消息机制主要由Handler.MessageQueue.Looper三个类组成,他们的主要作用是 Handler负责发送.处理Message MessageQueue负责维护Mess ...
- Android中的消息机制
在分析Android消息机制之前.我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- Android中的Parcel机制 实现Bundle传递对象
Android中的Parcel机制 实现了Bundle传递对象 使用Bundle传递对象,首先要将其序列化,但是,在Android中要使用这种传递对象的方式需要用到Android Parc ...
- 探索Android中的Parcel机制(上)
一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化……,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态 ...
随机推荐
- How Do I Declare A Block in Objective-C? [备忘]
How Do I Declare A Block in Objective-C? As a local variable: returnType (^blockName)(parameterTypes ...
- EBS业务学习之应收管理
Oracle Receivable 是功能完备地应收款管理系统,它能够有效地管理客户.发票和收帐过程,因此是财务模块的重要组成部分,是财务系统中较为核心的模块之一.对于一个公司来说,是否能够与客户保持 ...
- [shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39933993 shiro官网:http://shiro.apache.org/ shi ...
- 【移动开发】ViewPager缓存机制
1. 实现ViewPager的页面懒加载:在某些情况下,例如使用ViewPager查看多张大图,此时多张图片不能一次性载入,只有在浏览该页面时才载入(或者预先载入下一页面)页面的具体内容.2. ...
- java模拟链表
java语言不存在指针,但是我们仍可以用相应的逻辑模拟链表的实现,下面这段代码就是我的一个小伙伴实现的: package com.brucezhang.test; public class ...
- Android的四个基本概念(线程通信和GLSurfaceView)
GLSurfaceView提供了下列特性: 1> 管理一个surface,这个surface就是一块特殊的内存,能直接排版到android的视图view上. 2> 管理一个EGL disp ...
- Android的AdapterView及其子类简介-android学习之旅(二十三)
AdapterView简介 AdapterView组件是一类非常重要的组件,AdapterView本身是一根抽象基类,继承于ViewGroup,用法十分相似,只是显示形式不一样,因此同意讲解. Ada ...
- uploadify 3.2 java应用丢失session
flash中有个bug就是自身创建一个session,这样就导致与web本身的session不一致 权限验证失败的问题. 原因: 因为uploadify是不会自动传送session值的,所以当ses ...
- App会取代网站吗?
本文摘自<程序员的修炼:从优秀到卓越>,购买链接:http://product.china-pub.com/3769829 自1999年以来,不管是作为买家还是卖家,我一直是eBay的热心 ...
- Mybatis源码之(TypeAliasRegistry)TypeAlias别名实现机制
在Mybatis编程中我们经常会用到将某个bean作为参数类型parameterType或者结果返回值类型ResultType,所以很多时候我们需要把完成的Bean的包名在mapper文件中写上,如下 ...