Android Message 简单学习笔记(转载与整理)

转载 2013年12月04日 00:02:10

Message类用于android中多个线程间的通信,消息处理涉及的一个重要类是Handler,主要的功能是完成Activity的Widget与应用程序中线程之间的交互

Handler是消息的处理者,handler负责将需要传递的信息封装成Message,通过调用handler对象的obtainMessage()来实现;
将消息传递给Looper,这是通过handler对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。
当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler对象收到该消息后,调用相应的handler对象的handleMessage()方法
对其进行处理。

//不能在非主线程的线程里面更新UI

通俗讲就是在各个进程之间发送数据的处理对象。在任何进程中,只要获得了另一个进程的handler则可以通过 handler.sendMessage(message)方法向那个进程发送数据。基于这个机制,我们在处理多线程的时候可以新建一个thread,这 个thread拥有UI线程中的一个handler。当thread处理完一些耗时的操作后通过传递过来的handler向UI线程发送数据,由UI线程去更新界面。

开发带有Handler类的程序步骤如下。

在Activity或Activity的Widget中开发Handler类的对象,并重写handleMessage方法。

在新启动的线程中调用sendEmptyMessage或者sendMessage方法向Handler发送消息。

Handler类的对象用handleMessage方法接收消息,然后根据消息的不同执行不同的操作。


    在Android 中Handler和Message、Thread有着很密切的关系。Handler 主要是负责Message的分发和处理。但是这个Message从哪里来的呢?Message 由一个消息队列进行管理,而消息队列却由一个Looper进行管理。Android系统中Looper负责管理线程的消息队列和消息循环。 


可以通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得当前进程的主线程的 Looper对象。


Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消 息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该 线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。


虽说 特定线程的消息只能分发给本线程,不能进行跨线程通讯,但是由于可以通过获得线程的Looper对象来进行曲线的实现不同线程间消息的传递。



考虑线程间的通信如下:

1,只有一个主线程,主线程给自己发消息

发送消息:

Looper looper=Looper.getMainLooper();//获得主线程的Looper对象

MyHandler handler =new MyHandler(looper);//以主线程的Looper对象创建handler,所以这个handler发送的消息会被传递到主线程的MessageQueue

handler.removeMessage(0);
Message msg = handler.obtainMessage(1,1,1,"来自主线程的消息");//构建Message对象
//第一个参数:指定message代号,方便在handler接收消息时的处理
//第二三个参数没什么意义
//第四个参数封装的消息
handler.sendMessage(msg);//发送消息

接收消息和消息处理:
class MyHandler extends Handler{
public MyHandler(Looper looper){
super(looper);
}
public void handleMessage(Message msg){
super.handleMessage(msg);
textView.setText("主线程Hanlder,收到了消息:"+(String)msg.obj);
}
}
2.其他进程主线程发消息

发送消息:
   //主线程里启动了一个线程来操作消息的封装和发送的工作
   //这样原来主线程的发送就变成了其他线程的发送
    new MyThread().start();    

    //加了一个线程类用于发送消息
    class MyThread extends Thread{
        
        public void run(){
            Looper looper = Looper.getMainLooper(); //主线程的Looper对象
            //以主线程的Looper对象创建了handler,
            //这个handler发送的Message会被传递给主线程的MessageQueue。
            handler = new MyHandler(looper);

            //构建Message对象
            //第一个参数:是自己指定的message代号,方便在handler选择性地接收
            //第二三个参数没有什么意义
            //第四个参数需要封装的对象
            Message msg = handler.obtainMessage(1,1,1,"来自其他线程的消息");
            
            handler.sendMessage(msg); //发送消息            
        }
    }

接收消息和消息处理:
class MyHandler extends Handler{
public MyHandler(Looper looper){
super(looper);
}
public void handleMessage(Message msg){
super.handleMessage(msg);
textView.setText("主线程Hanlder,收到了消息:"+(String)msg.obj);
}
}

3.主线程给其他进程发消息

其他进程发送消息:
class MyThread extends Thread{
        
        public void run(){
            Looper.prepare(); //创建该线程的Looper对象,用于接收消息
            
            //注意了:这里的handler是定义在主线程中的
            //这里Looper.myLooper()获得的就是该线程的Looper对象,用来实例化主线程中的handler
            handler = new ThreadHandler(Looper.myLooper());
            
            //循环从MessageQueue中取消息。
            Looper.loop(); 


        }
        
        //定义线程类中的消息处理类
        class ThreadHandler extends Handler{
            
            public ThreadHandler(Looper looper){
                super(looper);
            }
            
            public void handleMessage(Message msg){
                //这里对该线程中的MessageQueue中的Message进行处理
                //返回给主线程一个消息
                handler = new MyHandler(Looper.getMainLooper());
                
                Message msg2 = handler.obtainMessage(1,1,1,"子线程收到:"+(String)msg.obj);
                
                handler.sendMessage(msg2);
            }
        }

主线程接收消息:
       //启动线程
        new MyThread().start();    
        
        btnTest.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                //这里handler的实例化在线程中
                //线程启动的时候就已经实例化了
                Message msg = handler.obtainMessage(1,1,1,"主线程发送的消息");
                handler.sendMessage(msg);
            }
        });
    }
    
    class MyHandler extends Handler{
        
        public MyHandler(Looper looper){
            super(looper);
        }
        
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            textView.setText("主线程的Handler,收到了消息:"+(String)msg.obj);
        }
    }
4.其他线程给自己发送消息:

    class MyHandler extends Handler{
        
        public MyHandler(Looper looper){
            super(looper);
        }
        
        public void handleMessage(Message msg){
            super.handleMessage(msg);
            textView.setText((String)msg.obj);
        }
    }    
    
    class MyThread extends Thread{
        
        public void run(){
            Looper.prepare(); //创建该线程的Looper对象
            //这里Looper.myLooper()获得的就是该线程的Looper对象了
            handler = new ThreadHandler(Looper.myLooper());
            Message msg = handler.obtainMessage(1,1,1,"我自己");
            handler.sendMessage(msg);
            
            Looper.loop(); 

        }
        
        //定义线程类中的消息处理类
        class ThreadHandler extends Handler{
            
            public ThreadHandler(Looper looper){
                super(looper);
            }
            
            public void handleMessage(Message msg){
                //这里对该线程中的MessageQueue中的Message进行处理
                //这里我们再返回给主线程一个消息
                //加入判断看看是不是该线程自己发的信息
                if(msg.what == 1 && msg.obj.equals("我自己")){
                    
                    handler = new MyHandler(Looper.getMainLooper());
                    
                    Message msg2 = handler.obtainMessage(1,1,1,"禀告主线程:我收到了自己发给自己的Message");
                    
                    handler.sendMessage(msg2);                
                }

            }
        }
    }


     

live555的有关代码学习笔记整理

一直很想做流媒体的直播,最近花时间看了有关live555的有关代码,这里隆重的推荐两篇:      http://blog.csdn.net/nkmnkm   (道长的文章,分析的很不错)   ...
  • sanmaoljh
  • sanmaoljh
  • 2015年10月07日 14:46
  • 289

3dmax笔记

1、用到最多的是平滑、线框和高光
  • luyuncsd123
  • luyuncsd123
  • 2013年12月07日 13:17
  • 642

WPF资源基础笔记

资源 WPF资源系统是一种保管一系列有用对象的简单方法,从而可以更容易的重用这些对象。 应用程序资源和程序集资源是不同的概念。 应用程序资源:可在应用程序中的其他部分使用。 程序集资源:是一块...
  • u011626294
  • u011626294
  • 2014年02月24日 12:41
  • 522

11.06笔记整理、作业以及学习心得

11.06课堂笔记及作业1、盒子模型内外边距和边框介绍当浏览器展现一个元素时,这个元素会占据一定的空间。这个空间由四个部分组成: 1. Margin 2. Border 3. Paddin...
  • huqiang0816
  • huqiang0816
  • 2017年11月06日 23:58
  • 38

Deep Learning(深度学习)学习笔记整理系列(三)

Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version...
  • lcj_cjfykx
  • lcj_cjfykx
  • 2015年02月25日 13:43
  • 1302

myBatis学习笔记(1)——快速入门

在项目中使用myBatis 导入jar包 在src下创建配置文件
  • u010837612
  • u010837612
  • 2015年05月12日 11:06
  • 947

GDB调试带参数的程序(转载+整理+实践)

GDB调试带参数的程序(转载+整理+实践) http://www.cnblogs.com/hankers/archive/2012/12/07/2806836.html 一.g...
  • blacet
  • blacet
  • 2016年08月31日 16:31
  • 691

live555学习笔记-几个重要对象的生命期

几个重要对象的生命期 live555中很多类,类与类之间的关系复杂,从属关系不明显,层次上看起来也有些乱.所以源代码读起来比较困难,对于一些对象生命的来龙去脉也很难厘清. 但这并不能说明live5...
  • Runningzyx
  • Runningzyx
  • 2016年09月19日 11:16
  • 367

TD-LTE学习笔记1

1、TD-LTE和LTE FDD的网络架构相同,不同之处主要体现在双工方式和工作频段,因此在整个网络架构中仅仅在eNodeB的设备实现方面存在差异,如滤波器、环形器和双工器等射频前端器件。 2、RS...
  • ymaym
  • ymaym
  • 2014年04月10日 09:39
  • 2516

android中handler中 obtainmessge与New message区别

obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new new需要重新申请,效率低,obtianmessage可以循环利用; //use Handler.obtainMe...
  • imdxt1986
  • imdxt1986
  • 2011年12月05日 11:42
  • 11419
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android Message 简单学习笔记(转载与整理)
举报原因:
原因补充:

(最多只允许输入30个字)