博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Looper,MessageQueue,Message,Handler
阅读量:4515 次
发布时间:2019-06-08

本文共 2901 字,大约阅读时间需要 9 分钟。

  Handler是android中线程间交互的一个方法,主要涉及Looper,MessageQueue,Message,Handler四个类。

  • 一个线程对应一个Looper,一个Looper拥有一个MessageQueue对象,Looper不断从MessageQueue中取出Message对象,然后执行Message对象对应的响应函数。
  • MessageQueue存放Message,使用next()函数取出一个Message,没有Message可取时,会阻塞当前线程。
  • Handler在定义的时候,会获取定义它的线程和线程对应的Looper对象(不存在会报错),Handler将Message加入Looper的MessageQueue中。
  • Message后持有添加自己的Handler的引用,Looper冲MessageQueue中取出Message会执行对应的Handler的handleMessage函数,这个函数就是我们自己定义的Message响应函数。

  1、Looper: android.os.Looper

  public final class Looper {  //不可有子类
      static final ThreadLocal
sThreadLocal = new ThreadLocal
();       final MessageQueue mQueue;
      ......
      public static void prepare() {
      prepare(true);       }       ......
      public static void loop() {
      final Looper me = myLooper();         ......       for (;;) {
      Message msg = queue.next(); // might block       if (msg == null) {
      return;       }
            msg.target.dispatchMessage(msg);
      }       }       ......
  }   Looper对象是和线程关联的,一个线程只能有一个唯一的Looper对象,Looper中维护着一个ThreadLocal对象,用来存放各个线程自己的looper对象。

   这里插一下对主线程运行的一个理解:一直知道UI线程是以一个死循环,监听用户和系统的事件,从而做出响应的,这个死循环保证UI线程可以一直存在。而android中UI线程的死循环就是通过Looper的loop方法实现的。在ActivityThread(一个UI线程是从这个类的main函数启动)的main函数中:先初始化当前线程的Looper对象,然后执行其他配置初始化等操作(包括了UI响应相关的Handler),最后执行Looper的loop函数阻塞UI线程等待Handler发送Message。所以我们在android开发中,UI线程中可以直接定义Handler,但是在子线程中,需要自己初始化Looper对象并开始一个循环。

   2、MessageQueue  android.os.MessageQueue

    public final class MessageQueue {            ......            Message next() {                  for(;;){                  }                 }         ........      }

  一个管理Message的队列。

  3、Message

    Message是用来传递消息的,Message的target属性持有发送他的Handler对象,所以后面可以使用到这个对象来调用消息的响应函数。

  4、Handler

    在Handler的多线程交互中,我们接触最多的就是Handler。

    1)我们定义自己的Handler:我们实现一个Handler实例的时候,Handler对象都会和实现他的线程的Looper和Looper的MessageQueue关联起来。

    2)我们使用Handler:我们在其他线程中,使用定义的Handler对象,发送Message,然后会调用Handler的一系列函数,将Message添加到MessageQueue中,等待Looper的使用。

public class Handler {
  ...... public void dispatchMessage(Message msg) {
    Looper中调用改方法消费Message     可能调用msg的callback(一个Runnable的对象)     调用mCallback对象(一个Handler的内部接口有handleMessage方法,有返回值) 调用Handler的handlerMessage方法 if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } ...... private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
将Message添加到MessageQueue msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }}

 

  

转载于:https://www.cnblogs.com/z964166725/p/8689970.html

你可能感兴趣的文章
浅谈虚拟机
查看>>
Ubuntu系统Linux编译osg库
查看>>
error MSB8008: 指定的平台工具集(v120)未安装或无效 解决办法
查看>>
BootstrapTable-导出数据
查看>>
Linux学习笔记 -- 系统目录结构
查看>>
[转载]ExtJs4 笔记(9) Ext.Panel 面板控件、 Ext.window.Window 窗口控件、 Ext.container.Viewport 布局控件...
查看>>
程序设计:找质数
查看>>
第三次作业结对编程
查看>>
Andorid Volley加载网络图片, 每次都会重新加载的问题
查看>>
php+layui数据表格实现数据分页渲染
查看>>
POJ-1077/HDU-1043
查看>>
pronunciation from Longman 2
查看>>
将数组排序组成最小的整数
查看>>
sqlserver学习--1(登陆,时间函数,查看表结构,查看建表语句,IDENTITY() 函数,查询表名称,查询表结构)...
查看>>
MYSQL 日期函数
查看>>
Oracle触发器之替代触发器
查看>>
NodeJS基础教程之一
查看>>
你真的了解SDWebImage吗?
查看>>
BZOJ 1101 Luogu P3455 POI 2007 Zap (莫比乌斯反演+数论分块)
查看>>
C#嵌套类
查看>>