zoukankan      html  css  js  c++  java
  • Looper,MessageQueue,Message,Handler

      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<Looper> sThreadLocal = new ThreadLocal<Looper>();

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

      

  • 相关阅读:
    R.java文件介绍
    Windows CE Notification API的使用方法
    Vue.js组件的重要选项
    Vue.js如何划分组件
    细数那些年我用过的前端开发工具
    前端几个常用简单的开发手册拿走不谢
    Bootstrap相关优质项目学习清单
    前端页面实现报警器提示音效果
    人工智能面试题86问,新手找工作必备!
    人工智能面试题86问,新手找工作必备!
  • 原文地址:https://www.cnblogs.com/z964166725/p/8689970.html
Copyright © 2011-2022 走看看