前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Android 异步操作】HandlerThread 示例 ( 初始化并执行 | 获取Looper | 获取 Handler | 获取消息队列 | 设置空闲队列 | 代码示例 )

【Android 异步操作】HandlerThread 示例 ( 初始化并执行 | 获取Looper | 获取 Handler | 获取消息队列 | 设置空闲队列 | 代码示例 )

作者头像
韩曙亮
发布2023-03-28 18:50:32
4740
发布2023-03-28 18:50:32
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

一、HandlerThread 初始化


初始化 HandlerThread , 特别注意 , 初始化完成后 , 紧跟着调用该线程的 start() 方法启动 ;

只有启动后 , HandlerThread 才会 初始化 Looper ,

Looper 初始化完成后 , 才能创建其中的 MessageQueue 消息队列 ,

有了 消息队列 MessageQueue , 才能获取 Handler ,

调用 getThreadHandler 方法获取 Handler , 或 自己创建 Handler ;

代码语言:javascript
复制
        // 1 . 初始化, 之后马上启动
        handlerThread = HandlerThread("handler")
        handlerThread.start()

HandlerThread -> Looper -> MessageQueue -> Handler

二、HandlerThread 获取Looper


HandlerThread 获取 Looper , 必须在 HandlerThread 启动之后 , 才能获取 Looper ;

代码语言:javascript
复制
        // 2 . 获取 Looper
        looper = handlerThread.looper

三、HandlerThread 获取消息队列 MessageQueue


HandlerThread 获取 MessageQueue , 从 Looper 中获取其中的 MessageQueue 消息队列 ,

在 6.0 之后 , 可以直接调用 getQueue 方法 , 获取消息队列 ,

在 6.0 之前 , 使用 反射 , 获取 Looper 中的 MessageQueue 消息队列 ;

代码语言:javascript
复制
        // 3 . 获取 消息队列 MessageQueue
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            messageQueue = looper.queue
        }else{
            // 反射获取 MessageQueue 消息队列
            // 设置访问字段
            var mQueue = Looper::class.java.getDeclaredField("mQueue")
            // 设置允许访问
            mQueue.isAccessible = true
            messageQueue = mQueue.get(looper) as MessageQueue
        }

四、HandlerThread 获取 Handler


创建 Handler , 可以通过上述获取的 子线程 Looper 创建 Handler , 将该 Looper 作为参数 , 传入 Handler 构造函数 , 即可创建该子线程对应的 Handler ;

该 Handler 运行在子线程中 , 因为该 Looper 是在子线程中 ;

代码语言:javascript
复制
        // 5 . 初始化 Handler
        handler = Handler(looper, {msg: Message ->
            Log.i(TAG, "运行任务 ${msg.what}")
            true
        })

五、HandlerThread 设置空闲队列


MessageQueue 消息队列 设置 IdleHandler 空闲任务 ,

IdleHandler 空闲任务实现 , 实现该 IdleHandler 接口的 queueIdle 方法 , 返回 true , 每次空闲时都会回调 , 如果返回 false , 则只会回调一次 ;

注册 IdleHandler , 调用 MessageQueue 消息队列的 addIdleHandler 注册空闲任务 ,

注销 IdleHandler , 调用 MessageQueue 消息队列的 removeIdleHandler 注销空闲任务

六、HandlerThread 代码示例


HandlerThread 代码示例 :

创建 HandlerThread , 注意创建后马上调用 start 方法执行 ,

获取对应的 Looper ,

获取 Looper 中封装的 消息队列 MessageQueue , 6.0 之后直接调用 getQueue 获取 , 6.0 之前使用反射获取 ,

设置空闲任务 IdleHandler , ( 可选 ) , 该空闲任务在 MessageQueue 队列为空时调用 , 一般用于刷新数据 , UI 等操作 ,

初始化 Handler , 可以自己创建 , 传入 Looper , 也可以调用 getLooper 方法获取系统提供的 Handler ,

使用 Handler 发送消息 ;

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

import android.os.*
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.os.MessageQueue
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlin.concurrent.thread

class MainActivity : AppCompatActivity() {
    val TAG = "MainActivity"

    lateinit var handlerThread : HandlerThread;
    lateinit var looper : Looper
    lateinit var messageQueue : MessageQueue
    lateinit var handler : Handler

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        handler()
    }

    fun handler(){
        // 1 . 初始化, 之后马上启动
        handlerThread = HandlerThread("handler")
        handlerThread.start()

        // 2 . 获取 Looper
        looper = handlerThread.looper

        // 3 . 获取 消息队列 MessageQueue
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            messageQueue = looper.queue
        }else{
            // 反射获取 MessageQueue 消息队列
            // 设置访问字段
            var mQueue = Looper::class.java.getDeclaredField("mQueue")
            // 设置允许访问
            mQueue.isAccessible = true
            messageQueue = mQueue.get(looper) as MessageQueue
        }

        // 4 . 注册 IdleHandler
        messageQueue.addIdleHandler {
            Log.i(TAG, "空闲任务")
            // 注意这里返回 true, 表示每次空闲任务都执行一次
            true
        }

        // 5 . 初始化 Handler
        handler = Handler(looper, {msg: Message ->
            Log.i(TAG, "运行任务 ${msg.what}")
            true
        })

        // 6 . 子线程中发送消息 0
        thread (start = true) {
            handler.sendEmptyMessage(0)
        }
        // 7 . 主线程发送消息 1
        handler.sendEmptyMessage(1)

    }

}

运行结果 :

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-11-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、HandlerThread 初始化
  • 二、HandlerThread 获取Looper
  • 三、HandlerThread 获取消息队列 MessageQueue
  • 四、HandlerThread 获取 Handler
  • 五、HandlerThread 设置空闲队列
  • 六、HandlerThread 代码示例
相关产品与服务
消息队列
腾讯云消息队列 TDMQ 是分布式架构中的重要组件,提供异步通信的基础能力,通过应用解耦降低系统复杂度,提升系统可用性和可扩展性。TDMQ 产品系列提供丰富的产品形态,包含 CKafka、RocketMQ、RabbitMQ、Pulsar、CMQ 五大产品,覆盖在线和离线场景,满足金融、互联网、教育、物流、能源等不同行业和场景的需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档