zoukankan      html  css  js  c++  java
  • Android之Message、handler学习

    学习来源:参考自http://www.eoeandroid.com/forum.php?mod=viewthread&tid=49595&highlight=handler

    一、相关概念

    1.MessageQueue:消息队列,一种数据结构,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue。通常使用Looper对象对该线程的MessageQueue管理。创建一个线程的时候,并不会自动为其创建MessageQueue。主线程创建时,会自动创建一个默认的Looper对象,而Looper对象的建立将自动创建一个MessageQueue。其他非主线程,不会自动创建Looper,需要的时候通过prepar函数实现。
    2.Message:消息对象,Message Queue中的存放的对象。一个Message Queue中包含多个Message。 
      Message实例对象的取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例,而是先看Message Pool(消息池)中是否有可用的Message实例,有则直接取出返回这个实例,否则使用给定的参数创建一个message对象。调用removeMessages()时,将message从message Queue中删除(如果带了int参数,只是将对应的message清空),同时放入到message pool中。除此,还可以通过handler对象的ObtainMessage()方法获取一个message实例。

    3.Looper:是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的。同时每一个Looper对象和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象,创建一个Looper对象时,会同时创建一个messagequeue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能接受Message。如需要接受,自己定义 一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。处理完成后,调用Message.recycle()将其放入Message Pool中。

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

    二、Handler的使用

    1.处理消息

     可以直接创建Handler实例,重写handlerMessage方法

    Handler myHandler = new Handler(){
                
                @Override
                public void handleMessage(Message msg){
                    super.handleMessage(msg);
                    doWork();
                }
            };

    也可以继承Handler,重写handlerMessage方法

    class MyHandler extends Handler{
            
            public MyHandler(Looper looper){
                super(looper);
            }
            
            @Override
            public void handleMessage(Message msg){
                
                super.handleMessage(msg);
                //textView.append((String)msg.obj); //子线程不能操纵UI
                Log.d("msg", (String)msg.obj);
            }
        }

    2.发送消息

      handler本身不仅可以发送消息,还可以用post的方式添加一个实现Runnable接口的匿名对象到消息队列中,在目标收到消息后就可以回调的方式在自己的线程中执行run的方法体。

     handler发送消息的常用方法:

              post(Runnable)
              postAtTime(Runnable,long)
              postDelayed(Runnable long)
              sendEmptyMessage(int what)
              sendMessage(Message)
              sendMessageAtTime(Message,long)
              sendMessageDelayed(Message,long)

    三、通信

    1.主线程给自己发送message

    public class MainActivity extends Activity {
    
        private TextView textView;
        private int i = 0;
        @Override
        public void onCreate(Bundle savedInstanceState){
            
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            textView = (TextView) findViewById(R.id.text);
        }
        
        public void onTouch(View v){
            Looper looper = Looper.getMainLooper(); //主线程的Looper
            //以主线程的Looper创建Handler,该handler发送的Message会传递给主线程的MessageQueue
            MyHandler handler = new MyHandler(looper); 
            handler.removeMessages(0);
            Message msg = handler.obtainMessage(1, 1, 1, "主线程Test" + i++);
            handler.sendMessage(msg);
        }
        
        class MyHandler extends Handler{
            public MyHandler(Looper looper){
                super(looper);
            }
            
            @Override
            public void handleMessage(Message msg){
                
                super.handleMessage(msg);
                textView.append((String)msg.obj);
            }
        }
    }

    2.子线程给主线程发消息

    public class MainActivity extends Activity {
    
        private TextView textView;
        private int i = 0;
        private MyHandler handler;
        @Override
        public void onCreate(Bundle savedInstanceState){
            
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            textView = (TextView) findViewById(R.id.text);
        }
        
        public void onTouch(View v){
            MyThread mRunnable = new MyThread();
            Thread thread = new Thread(mRunnable);
            thread.start();
        }
        
        class MyHandler extends Handler{
            public MyHandler(Looper looper){
                super(looper);
            }
            
            @Override
            public void handleMessage(Message msg){
                
                super.handleMessage(msg);
                textView.append((String)msg.obj);
            }
        }
        
        class MyThread implements Runnable{
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                Looper looper = Looper.getMainLooper();
                //以主线程的Looper创建Handler,该handler发送的Message会传递给主线程的MessageQueue
                handler = new MyHandler(looper);
                Message message = handler.obtainMessage(1, "子线程——>主线程Test" + i++);
                handler.sendMessage(message);
            }
            
        }

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

    public class MainActivity extends Activity {
    
        private TextView textView;
        private int i = 0;
        private Handler handler;
        @Override
        public void onCreate(Bundle savedInstanceState){
            
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            textView = (TextView) findViewById(R.id.text);
            
            MyThread mRunnable = new MyThread();
            Thread thread = new Thread(mRunnable);
            thread.start();
        }
        
        public void onTouch(View v){
            Message message = handler.obtainMessage(1, "主线程——>子线程Test" + i++);
            handler.sendMessage(message);
        }
        
        class MyThread implements Runnable{
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                Looper.prepare(); //创建该线程的Looper
                Looper looper = Looper.myLooper();
                //以子线程的Looper创建Handler,该handler发送的Message会传递给子线程的MessageQueue
                handler = new ThreadHandler(looper);
                Looper.loop();//循环从messagequeue中取消息
            }
            
        }
        
        class ThreadHandler extends Handler{
            
            public ThreadHandler(Looper looper){
                super(looper);
            }
            
            @Override
            public void handleMessage(Message msg){
                
                super.handleMessage(msg);
                //textView.append((String)msg.obj); //子线程不能操纵UI
                Log.d("msg", (String)msg.obj);
            }
        }
    }

    4.其他线程给自己发消息

    public class MainActivity extends Activity {
    
        private TextView textView;
        private int i = 0;
        private Handler handler;
        @Override
        public void onCreate(Bundle savedInstanceState){
            
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            textView = (TextView) findViewById(R.id.text);
            
            
        }
        
        public void onTouch(View v){
            MyThread mRunnable = new MyThread();
            Thread thread = new Thread(mRunnable);
            thread.start();
        }
        
        class MyThread implements Runnable{
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                Looper.prepare(); //创建该线程的Looper
                Looper looper = Looper.myLooper();
                //以子线程的Looper创建Handler,该handler发送的Message会传递给子线程的MessageQueue
                handler = new ThreadHandler(looper);
                Message message = handler.obtainMessage(1, "子线程——>子线程Test" + i++);
                handler.sendMessage(message);
                //循环从messagequeue中取消息
                Looper.loop();
            }
            
        }
        
        class ThreadHandler extends Handler{
            
            public ThreadHandler(Looper looper){
                super(looper);
            }
            
            @Override
            public void handleMessage(Message msg){
                
                super.handleMessage(msg);
                //textView.append((String)msg.obj); //子线程不能操纵UI
                Log.d("msg", (String)msg.obj);
            }
        }
    }
  • 相关阅读:
    通过intent启动Activity
    ubuntu12.04的NFS配置
    内核添加对yaffs2文件系统的支持
    linux内核移植到S5pv210
    nand驱动移植
    tiny210V2 Uboot kernel filesystem 烧写和启动
    linux C++通过ntp协议获取网络时间
    tiny210移植linux内核(3.0.8)杂项
    Ubuntu系统中Sogou输入法面板问题解决方案
    Ubuntu系统中登陆阿里云服务器的方法
  • 原文地址:https://www.cnblogs.com/xuepeng0521/p/4432327.html
Copyright © 2011-2022 走看看