欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android中message、messageQueue、Handler、looper的关系

程序员文章站 2022-07-14 17:05:24
...

定义

message(消息):
1,线程间交流的消息
2,通常用于后台数据传递给ui线程
3,在Handler类中的handleMessage方法中得到单个的message进行处理

messageQueue(消息队列):
1,用来存放通过Handler发布的消息
2,通常附属于某一个创建它的线程
3,通过Looper.myQueue()得到当前线程的messageQueue

handler(处理者):
1,负责Message的发送,Message内容的执行处理;
2,操作一个Runnable
3,handler只会将message发送到与它关联的messageQueue
4,它只能处理当前messageQueue中的message
5,接受到message后调用handleMessage进行处理
6,使用Handler,需要implement 该类的 handleMessage(Message)方法

looper(通讯桥梁):
1,Handler和messageQueue之间的通讯桥梁
2,程序通过Handler把message传递给Looper,Looper把message放入messageQueue
3,Looper把messageQueue里的message广播给所有的Handler
4,Handler接受到message后调用handleMessage进行处理

要点

1, 每个messageQueue都会有一个对应的Handler。
2,Handler会向messageQueue通过两种方法发送消息:sendMessage或post
3,sendMessage和post都会插在messageQueue队尾并按先进先出执行,队列形式。
4,通过sendMessage发送的是一个message对象,会被 Handler的handleMessage()函数处理
5,通过post方法发送的是一个runnable对象,会被自己的Runnable方法执行
6,Android没有全局的messageQueue
7,Android会自动替主线程(UI线程)建立messageQueue,但在子线程里并没有建立messageQueue
8,ui线程里,调用Looper.getMainLooper()得到的主线程的Looper不为NULL,,但调用Looper.myLooper() 得到当前线程的Looper就有可能为NULL
9,对子线程使用Looper的流程:
1-> 在Looper.loop()方法运行开始后,循环地按照接收顺序取出Message Queue里面的非NULL的Message。

2- >一开始Message Queue里面的Message都是NULL的。
当Handler.sendMessage(Message)到Message Queue,该函数里面设置了那个Message对象的target属性是当前的Handler对象。
随后Looper取出了那个Message,则调用 该Message的target指向的Hander的dispatchMessage函数对Message进行处理。

在dispatchMessage方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:
1) Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;
2) Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;
3) 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage 函数处理消息。
由此可见,我们实现的handleMessage方法是优先级最低的!

3->Handler处理完该Message (update UI) 后,Looper则设置该Message为NULL,以便回收!
判断Handler对象里面的Looper对象是属于哪条线程的,则由该线程来执行!
1,当Handler对象的构造函数的参数为空,则为当前所在线程的Looper;
2, Looper.getMainLooper()得到的是主线程的Looper对象。

使用

private Handler hd = new MyHandler();

new Thread(new Runnable() {
        @Override
        public void run() { // 新建一个线程,并新建一个Message的对象,是用Handler的对象发送这个Message
          Message msg = new Message();
          msg.what = UPDATE_TEXT; // 用户自定义的一个值,用于标识不同类型的消息
          hd.sendMessage(msg); // 发送消息
        }
      }).start();


// 定义一个内部类继承自Handler,并且覆盖handleMessage方法用于处理子线程传过来的消息
  class MyHandler extends Handler{
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      switch (msg.what) {
      case UPDATE_TEXT: // 接受到消息之后,对UI控件进行修改
        tv.setText("修改成功!");
        break;

      default:
        break;
      }
    }
  }
相关标签: android 线程