【Android 异步操作】手写 Handler ( Handler 发送与处理消息 | Handler 初始化 | 完整 Handler 代码 )

2023-03-28 18:47:53 浏览数 (2)

文章目录

  • 一、Handler 发送与处理消息 ( 两大功能 )
  • 二、Handler 初始化
  • 三、完整 Handler 代码

一、Handler 发送与处理消息 ( 两大功能 )


Handler 有两个功能 :

功能一 : 发送消息到 Looper 中的 消息队列 MessageQueue 中 ;

代码语言:javascript复制
    /**
     * 发送消息
     * @param msg
     */
    public void sendMessage(Message msg){
        // 为消息设置发送的 Handler
        msg.target = this;
        // 向消息队列中放入要执行的消息
        mQueue.enqueueMessage(msg);
    }

功能二 : 接收 Looper 中的 loop 方法传来的 Message , 并 执行该 Message 代表的任务 ;

Handler 执行 Message 任务 , 具体的执行逻辑需要 用户实现 ; 用户创建 Handler 时 , 需要覆盖 handleMessage 方法 , 在重写的方法中处理不同的 Message 任务 ;

代码语言:javascript复制
    /**
     * 执行消息对应的任务
     * @param next
     */
    public void handleMessage(Message next) {

    }

二、Handler 初始化


Handler 初始化 :

Handler 的功能一 发送消息 , 就是向 消息队列 MessageQueue 中发送消息 , 并将消息放到 MessageQueue 中的 Message 链表队列的最后一个 ;

这就需要 Handler 持有 消息队列 MessageQueue 的引用 ,

消息队列封装在 Looper 中 , 因此需要先拿到 线程本地变量 Looper , 然后从 Looper 中获取对应的消息队列 ;

这里就需要特别注意 , 在初始化 Handler 时 , 需要用到 Looper , 如果 Looper 为空 , Handler 初始化就会失败 ;

因此在 创建 Handler 之前 , 必须先调用 Looper 的 prepare 方法 , 先将 Looper 进行初始化操作 ;

代码语言:javascript复制
    /**
     * 消息队列
     * 该消息队列封装在 Looper 中
     * Looper 封装在线程本地变量中
     */
    MessageQueue mQueue;

    public Handler(){
        /*
            在 Handler 中需要拿到 Looper
            进而拿到 Looper 中的 MessageQueue 消息队列

            Handler 的操作就是将 Message 放入 MessageQueue
            因此在 Handler 中需要持有 MessageQueue 消息队列的引用


            获取 Looper 时 , Looper 必须已经初始化完毕,
            也就是已经调用过 prepare 创建了 Looper 并将其放入了线程本地变量
         */

        // 获取当前线程中的 线程本地变量 Looper
        Looper looper = Looper.looper();

        // 获取封装在 Looper 中的 消息队列 MessageQueue
        mQueue = looper.mQueue;
    }

三、完整 Handler 代码


代码语言:javascript复制
package kim.hsl.handler;

public class Handler {

    /**
     * 消息队列
     * 该消息队列封装在 Looper 中
     * Looper 封装在线程本地变量中
     */
    MessageQueue mQueue;

    public Handler(){
        /*
            在 Handler 中需要拿到 Looper
            进而拿到 Looper 中的 MessageQueue 消息队列

            Handler 的操作就是将 Message 放入 MessageQueue
            因此在 Handler 中需要持有 MessageQueue 消息队列的引用


            获取 Looper 时 , Looper 必须已经初始化完毕,
            也就是已经调用过 prepare 创建了 Looper 并将其放入了线程本地变量
         */

        // 获取当前线程中的 线程本地变量 Looper
        Looper looper = Looper.looper();

        // 获取封装在 Looper 中的 消息队列 MessageQueue
        mQueue = looper.mQueue;
    }

    /**
     * 发送消息
     * @param msg
     */
    public void sendMessage(Message msg){
        // 为消息设置发送的 Handler
        msg.target = this;
        // 向消息队列中放入要执行的消息
        mQueue.enqueueMessage(msg);
    }


    /**
     * 执行消息对应的任务
     * @param next
     */
    public void handleMessage(Message next) {

    }
}

0 人点赞