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);
        }
    }
}
时间: 2024-08-04 14:36:46

Android之Message、handler学习的相关文章

Android handler学习笔记

调用Message.obtain()从消息池中获得一个message对象,而不是直接new一个message对象,可以节省内存开销.也可以用handler.obtainMessage(),其实是一样的,obtainMessage()就是返回Message.obtain() message.sendToTarget()跟handler.sendMessage()是一样的 下面的方式可以拦截Message. private Handler handler=new Handler(new Callba

Android 中Message,MessageQueue,Looper,Handler详解+实例

一.几个关键概念 1.MessageQueue:是一种数据结构,见名知义,就是一个消息队列,存放消息的地方.每一个线程最多只可以拥有一个MessageQueue数据结构. 创建一个线程的时候,并不会自动创建其MessageQueue.通常使用一个Looper对象对该线程的MessageQueue进行管理.主线程创建时,会创建一 个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue.其他非主线程,不会自动创建Looper,要需要的时候,通过调 用prepar

Android(java)学习笔记134:Handler用法总结和秒表案例

一.Handler的定义: Handler主要接收子线程发送的数据, 并用此数据配合主线程更新UI,用来跟UI主线程交互用.比如可以用handler发送一个message,然后在handler的线程中来接收.处理该消息,以避免直接在UI主线程中处理事务导致影响UI主线程的其他处理工作,Android提供了Handler作为主线程和子线程的纽带:也可以将handler对象传给其他进程,以便在其他进程中通过handler给你发送事件:还可以通过handler的延时发送message,可以延时处理一些

Android消息处理机制(Handler 与Message)---01

一.handler的使用场景为么会有handler?(部分内容图片摘自http://www.runoob.com/w3cnote/android-tutorial-handler-message.html) 如有侵犯,请告知. 二.handler的消息处理机制 在Android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长时间的任务后做出相应的通知. UI线程:就是我们的主线程,系统在创建UI线程的时候会初始化一个Looper对象,同时也会创建一个与其关联的Message

深入源码解析Android中的Handler,Message,MessageQueue,Looper

本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文< Android中Handler的使用>,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解. 概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制.我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功能.但

【Android自助餐】Handler消息机制完全解析(一)Message中obtain()与recycle()的来龙去脉

[Android自助餐]Handler消息机制完全解析(一)Message中obtain()与recycle()的来龙去脉 Android自助餐Handler消息机制完全解析一Message中obtain与recycle的来龙去脉 提供obtain 回收recycle 提供obtain() 在obtain的所有重载方法中,第一行都是Message m = obtain();,即调用空参的方法. 先来看一下这个空参方法 public static Message obtain() { synchr

Android开发:Handler异步通信机制全面解析(包含Looper、Message Queue

前言 最近刚好在做关于异步通信的需求,那么,今天我们来讲解下Android开发中的Handler异步通信传递机制(包括Looper.Message Queue) 目录 定义 Android提供的一套消息传递机制 作用 用于实现子线程对UI线程的更新,实现异步消息的处理: - 在新启动的线程中发送消息 - 在主线程中获取并处理信息 为什么要用Handler 在安卓开发中: - 为了保证Android的UI操作是线程安全的,Android规定了只允许UI线程修改Activity里的UI组件: - 但

Android之Message,MessageQueue,Looper,Handler详解(带示例)

一.几个关键概念 1.MessageQueue:是一种数据结构,见名知义,就是一个消息队列,存放消息的地方.每一个线程最多只可以拥有一个MessageQueue数据结构. 创建一个线程的时候,并不会自动创建其MessageQueue.通常使用一个Looper对象对该线程的MessageQueue进行管理.主线程创建时,会创建一 个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue.其他非主线程,不会自动创建Looper,要需要的时候,通过调 用prepar

Android 中Thread,Handler,Loop学习

1.先看一下最简单的进度条示例 EG: package com.sxz.android.thread; import java.util.concurrent.atomic.AtomicBoolean;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.ProgressBar;public cla