zoukankan      html  css  js  c++  java
  • 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对象发送出去。

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


    Meet so Meet. C plusplus I-PLUS....
  • 相关阅读:
    Spring ListFactoryBean实例
    Spring集合 (List,Set,Map,Properties) 实例
    Spring Bean作用域实例
    Spring内部bean实例
    Spring bean加载多个配置文件
    如何注入值到Spring bean属性
    Spring Bean引用例子
    Spring构造方法注入类型歧义
    Spring JavaConfig @Import实例
    Spring JavaConfig实例
  • 原文地址:https://www.cnblogs.com/iplus/p/4467410.html
Copyright © 2011-2022 走看看