关闭

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

362人阅读 评论(0) 收藏 举报
分类:

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);                
                }

            }
        }
    }


     

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:12115次
    • 积分:336
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:6篇
    • 译文:1篇
    • 评论:0条
    文章分类
    文章存档