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

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

文章目录

一、HandlerThread 初始化

二、HandlerThread 获取Looper

三、HandlerThread 获取消息队列 MessageQueue

四、HandlerThread 获取 Handler

五、HandlerThread 设置空闲队列

六、HandlerThread 代码示例





一、HandlerThread 初始化


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


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


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


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


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


 

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



HandlerThread -> Looper -> MessageQueue -> Handler






二、HandlerThread 获取Looper


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


   

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





三、HandlerThread 获取消息队列 MessageQueue


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


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


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


   

// 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 是在子线程中 ;


   

// 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 发送消息 ;


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



运行结果 :


image.png

目录
相关文章
|
消息中间件 Android开发
Android Handler的使用方式以及其机制的简单介绍
Handler 是 Android 中实现线程间通信的重要机制,可传递任意两线程数据。常用场景包括子线程向主线程(UI 线程)传递结果,以及主线程向子线程发送消息。其核心涉及四个类:Handler(发送/接收消息)、Message(消息载体)、MessageQueue(消息队列)和 Looper(消息循环泵)。基本流程为:Handler 发送 Message 至 MessageQueue,Looper 从队列中按 FIFO 取出并处理。
468 0
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
|
安全 Java 网络安全
Android远程连接和登录FTPS服务代码(commons.net库)
Android远程连接和登录FTPS服务代码(commons.net库)
535 1
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
497 1
|
消息中间件 存储 Java
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
648 2
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异:从代码到用户体验
【10月更文挑战第5天】在移动应用开发的广阔天地中,安卓和iOS两大平台各占半壁江山。它们在技术架构、开发环境及用户体验上有着根本的不同。本文通过比较这两种平台的开发过程,揭示背后的设计理念和技术选择如何影响最终产品。我们将深入探讨各自平台的代码示例,理解开发者面临的挑战,以及这些差异如何塑造用户的日常体验。
|
消息中间件 C语言 RocketMQ
消息队列 MQ操作报错合集之出现"Connection reset by peer"的错误,该如何处理
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
消息中间件
手撸MQ消息队列——循环数组
队列是一种常用的数据结构,类似于栈,但采用先进先出(FIFO)的原则。生活中常见的排队场景就是队列的应用实例。在数据结构中,队列通常用数组实现,包括入队(队尾插入元素)和出队(队头移除元素)两种基本操作。本文介绍了如何用数组实现队列,包括定义数组长度、维护队头和队尾下标(front 和 tail),并通过取模运算解决下标越界问题。此外,还讨论了队列的空与满状态判断,以及并发和等待机制的实现。通过示例代码展示了队列的基本操作及优化方法,确保多线程环境下的正确性和高效性。
503 0
手撸MQ消息队列——循环数组