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

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。