学习HandlerThread

news2024/9/29 13:15:48

HandlerThread是一个扩展了Thread的类。也就意味着它和普通的Thread类的调用没有什么区别,仍然要调用start()请添加图片描述
如上图所示,扩展后的HandlerThread类有一个Looper和Handler。
关于这一块的知识可以参考一下《关于Handler我们应该知道的知识》

HandlerThread的run方法:

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

调用了start()就是启动了一个线程,这个线程首先就创建了一个Looper。

  • Looper.prepare();是为当前线程准备好一个Looper,
  • Looper.myLooper();是取回创建好的Looper。
  • onLooperPrepared();如果运行消息队列前要设置一些东西,可以重写这个方法
  • Looper.loop();在此线程中运行消息队列

要停止已启动的Looper,必须要调用Looper的quit()方法,HandlerThread就有这么一个方法:

public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }

  • getLooper();拿到HandleThread实例里的Looper
  • looper.quit();结束当前线程的Looper

说了这么多,结合我上一篇文章《关于Handler我们应该知道的知识》我们知道HandlerThread提供了一种便利给在线程中创建Looper来处理我们的任务。

虽然HandlerThread类里有getThreadHandler()方法得到Handler,但是你不可能调用到它。这个方法用@hide注释了

/**
     * @return a shared {@link Handler} associated with this thread
     * @hide
     */
    @NonNull
    public Handler getThreadHandler() {
        if (mHandler == null) {
            mHandler = new Handler(getLooper());
        }
        return mHandler;
    }

@hide 它实际是控制了android.jar包的东西

我们在另一篇文章里再说@hide的东西吧。我们继续说HandlerThread。

因此我们只能自己创建一个Handler实例去绑定HandlerThread线程的Looper:

这样的我们的任务就可以放到其他的线程去执行了。来个实例吧!

 val handlerThread = HandlerThread("Hello")

        handlerThread.start() // 要在绑定Handler前调用,否则Looper就没有创建好

        val handler = object: Handler(handlerThread.looper) {
            override fun handleMessage(msg: Message) {
                println("Hello world8888888888888888888")
            }
        }

        handler.sendMessage(Message.obtain())

        handler.sendMessage(Message.obtain())

        Thread.sleep(3000)
        handlerThread.quit()// 不再使用的话,要记得停到Looper
        // 收到error java.lang.IllegalStateException: Handler ... 
        // sending message to a Handler on a dead thread
        handler.sendMessage(Message.obtain()) 

比如我们自己创建一个线程,并让它启动一个Looper来帮我们做事:

var mLooper: Looper? = null
// 启动一个线程,并为当前线程
Thread{
    Looper.prepare()
    synchronized(this) {
        mLooper = Looper.myLooper()
    }
    Looper.loop()
}.start()

Thread.sleep(3000) // Looper创建是要些时间的,所以我们等一下它。

val myHandler = object: Handler(mLooper!!){
     override fun handleMessage(msg: Message) {
        println("Hey world @@@@@@@@@")
     }
 }

myHandler.sendMessage(Message.obtain())

优雅一点的版本,java的会更简单些:

 var mLooper: Looper? = null
        val lock = ReentrantLock()
        val condition = lock.newCondition()
        Thread{
            Looper.prepare()
            try {
                lock.lock()
                mLooper = Looper.myLooper()
                condition.signalAll()
            }catch (e: Exception){

            }finally {
                lock.unlock()
            }

            Looper.loop()
        }.start()

        try {
            lock.lock()
            if (mLooper == null) condition.await()
        }catch (e: Exception){
            e.printStackTrace()
        }finally {
            lock.unlock()
        }

        val myHandler = object: Handler(mLooper!!){
            override fun handleMessage(msg: Message) {
                println("Hey world @@@@@@@@@")
            }
        }

        myHandler.sendMessage(Message.obtain())

就这么多,谢谢捧场!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/339095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

普冉PY32系列(五) 使用JLink RTT代替串口输出日志

目录 普冉PY32系列(一) PY32F0系列32位Cortex M0 MCU简介普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境普冉PY32系列(三) PY32F002A资源实测 - 这个型号不简单普冉PY32系列(四) PY32F002A/003/030的时钟设置普冉PY32系列(五) 使用JLink RTT代替串口输出日志 JLink …

Python-第五天 Python函数

Python-第五天 Python函数一、函数介绍1. 什么事函数二、函数的定义1.函数的定义:2.案例三、函数的参数1.函数的传入参数2.案例升级四、函数的返回值1.什么是返回值2.返回值的语法3.None类型4.None类型的应用场景五、函数说明文档1.函数的说明文档2.在PyCharm中查看…

脑机接口协议V1.0

脑机接口,有时也称作“大脑端口”direct neural interface或者“脑机融合感知”brain-machine interface,它是在人或动物脑(或者脑细胞的培养物)与外部设备间建立的直接连接通路。在单向脑机接口的情况下,计算机或者接…

leaflet显示高程

很多地图软件都能随鼠标移动动态显示高程。这里介绍一种方法,我所得出的。1 下载高程数据一般有12.5m数据下载,可惜精度根本不够,比如mapbox的免费在线的,或者91卫图提供百度网盘打包下载的,没法用,差距太大…

记录robosense RS-LIDAR-16使用过程3

一、wireshark抓包保存pcap文件并解析ubuntu18安装wireshark,参考下面csdn教程,官网教程我看的一脸蒙(可能英语太差)https://blog.csdn.net/weixin_46048542/article/details/121730448?spm1001.2101.3001.6650.2&utm_medium…

秒杀项目之服务调用分布式session

目录 nginx动静分离 服务调用 创建配置zmall-cart购物车模块 创建配置zmall-order订单模块 服务调用 spring session实战 什么是Spring Session 为什么要使用Spring Session 错误案例展示 配置spring-session 二级域名问题 用户登录 nginx动静分离 第1步&#xff…

如何用演示程序检测K100|K720|K750电动发卡读写一体机性能

K100|K720|K750电动发卡读写一体机采用工业级设 计,表面烤漆处理,具有良好的耐磨耐腐蚀性。适应各种高、低温, 多灰尘等 恶劣环境。其发卡原理为拟人型摩擦式发卡,对各类变形卡有非常好的适应性。 CNC的精度保证卡距的绝对一致性、…

Filter过滤器完成验证代码的封装

Filter过滤器完成验证代码的封装filter是什么1 使用filter2 filter配置到项目中验证用户权限是需要反复使用的代码块,把他封装到filter中,减少代码冗余filter是什么 init()方法:初始化方法,在创建Filter后立即调用。可用于完成初始…

刚刚,体验了一把Bing chat很爽

文章目录刚刚,体验了一把Bing chat很爽你能做啥?与chatgpt有什么不同?以下是Bingchat的 10个新功能1⃣️在网上搜索结果2⃣️摘要链接3⃣️对话助手4⃣️向您发送实际信息,正确的链接5⃣️在单个查询中执行多个搜索6⃣️玩冒险游戏…

内网渗透(十八)之Windows协议认证和密码抓取-本地认证(NTML哈希和LM哈希)

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

【Web测试】各类web控件测试点汇总,软测人必备

一 、界面检查 进入一个页面测试,首先是检查title,页面排版,字段等,而不是马上进入文本框校验 1、页面名称title是否正确 2、当前位置是否可见 您的位置:xxx>xxxx 3、文字格式统一性 4、排版是否整齐 5、列表项显示…

leetcode: 3Sum

leetcode: 3Sum1. 题目描述2. 思考3. 解题3. 总结1. 题目描述 Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i ! j, i ! k, and j ! k, and nums[i] nums[j] nums[k] 0. Notice that the solution set must not contain …

爬虫Python入门好学吗?学什么?

爬虫Python入门好学吗?学爬虫需要具备一定的基础,有编程基础学Python爬虫更容易学。但要多看多练,有自己的逻辑想法。用Python达到自己的学习目的才算有价值。如果是入门学习了解,开始学习不难,但深入学习有难度&#…

2022年12月电子学会Python等级考试试卷(一级)答案解析

青少年软件编程(Python)等级考试试卷(一级) 一、单选题(共25题,共50分) 1. 关于Python语言的注释,以下选项中描述错误的是?( ) A. Python语言有两种注释方式&…

JavaEE16-Spring事务和事务传播机制

目录 1.为什么需要事务? 2.MySQL中事务的使用 3.Spring中事务的实现 3.1.编程式事务(手动写代码操作事务) 3.2.声明式事务(利用注解自动开启和提交事务)(使用为主) 3.2.1.Transactional作用范围 3.2.2.Transact…

JetpackCompose从入门到实战学习笔记8—ConstraintLayout的简单使用

JetpackCompose从入门到实战学习笔记8—ConstraintLayout的简单使用 1.简介: Compose 中的 ConstraintLayout ConstraintLayout 是一种布局,让您可以相对于屏幕上的其他可组合项来放置可组合项。它是一种实用的替代方案,可代替使用多个已嵌…

JVM垃圾回收机制GC理解

目录JVM垃圾回收分代收集如何识别垃圾引用计数法可达性分析法引用关系四种类型: 强、软、弱、虚强引用软引用 SoftReference弱引用 WeakReferenceWeakHashMap软引用与虚引用的使用场景虚引用与引用队列引用队列虚引用 PhantomReference垃圾回收算法引用计数复制 Cop…

06- 梯度下降(SGDRegressor) (机器学习)

梯度下降算法也是先构建误差值的函数, 通过求误差值函数的最小值来达到误差最小的目的, 不过梯度下降是先随机取值, 然后求函数在该点的导数, 如果导数为正, 下一次取值向反方向移动, 如果导数为负, 正向移动, 直到导数取值极小时, 认定误差达到一个可以接受的范围, 然后导出相…

解读手机拍照的各个参数(拍照时,上面会有6个符号)

1第一个符号是闪光灯符号,如下图所示。有四种模式, 手机的闪光灯分别为关闭、自动、开启和常亮四种状态。 关闭:就是在任何情况下都不会闪光 自动:由手机来判断此时的光线强弱,若手机测光认为光线太弱,则…

前端限制 git commit 提交格式

团队开发中,每个人 git commit 的习惯都不一样,这样不利于对更新日志的筛选,也可以防止同事跑路后,出现 bug 后,看不懂他当时提交的日志究竟是改了个 bug 还是新增了一个功能,影响开发效率。 这时候就需要…