Android HandlerThread 总结使用

Android HandlerThread 总结使用

转载请标明出处:http://www.cnblogs.com/zhaoyanjun/p/6062880.html
本文出自【赵彦军的博客】

前言

以前我在 【Android Handler、Loop 的简单使用】 介绍了子线程和子线程之间的通信。
这里写图片描述

很明显的一点就是,我们要在子线程中调用Looper.prepare() 为一个线程开启一个消息循环,默认情况下Android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。) Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。 然后通过Looper.loop() 让Looper开始工作,从消息队列里取消息,处理消息。

注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。

然而这一切都可以用HandlerThread类来帮我们做这些逻辑操作。

HandlerThread

HandlerThread本质上就是一个普通Thread,只不过内部建立了Looper.

HandlerThread的常规用法

  • 创建一个HandlerThread

mThread = new HandlerThread("handler_thread");

  • 启动一个HandlerThread

    mThread.start();

  • 退出循环
    Looper是通过调用loop方法驱动着消息循环的进行: 从MessageQueue中阻塞式地取出一个消息,然后让Handler处理该消息,周而复始,loop方法是个死循环方法。

那如何终止消息循环呢?我们可以调用Looper的quit方法或quitSafely方法,二者稍有不同。

 /*** Quits the looper.* <p>* Causes the {@link #loop} method to terminate without processing any* more messages in the message queue.* </p><p>* Any attempt to post messages to the queue after the looper is asked to quit will fail.* For example, the {@link Handler#sendMessage(Message)} method will return false.* </p><p class="note">* Using this method may be unsafe because some messages may not be delivered* before the looper terminates.  Consider using {@link #quitSafely} instead to ensure* that all pending work is completed in an orderly manner.* </p>** @see #quitSafely*/public void quit() {mQueue.quit(false);}/*** Quits the looper safely.* <p>* Causes the {@link #loop} method to terminate as soon as all remaining messages* in the message queue that are already due to be delivered have been handled.* However pending delayed messages with due times in the future will not be* delivered before the loop terminates.* </p><p>* Any attempt to post messages to the queue after the looper is asked to quit will fail.* For example, the {@link Handler#sendMessage(Message)} method will return false.* </p>*/public void quitSafely() {mQueue.quit(true);}

相同点:
将不在接受新的事件加入消息队列。

不同点
当我们调用Looper的quit方法时,实际上执行了MessageQueue中的removeAllMessagesLocked方法,该方法的作用是把MessageQueue消息池中所有的消息全部清空,无论是延迟消息(延迟消息是指通过sendMessageDelayed或通过postDelayed等方法发送的需要延迟执行的消息)还是非延迟消息。

当我们调用Looper的quitSafely方法时,实际上执行了MessageQueue中的removeAllFutureMessagesLocked方法,通过名字就可以看出,该方法只会清空MessageQueue消息池中所有的延迟消息,并将消息池中所有的非延迟消息派发出去让Handler去处理,quitSafely相比于quit方法安全之处在于清空消息之前会派发所有的非延迟消息。

无论是调用了quit方法还是quitSafely方法只会,Looper就不再接收新的消息。即在调用了Looper的quit或quitSafely方法之后,消息循环就终结了,这时候再通过Handler调用sendMessage或post等方法发送消息时均返回false,表示消息没有成功放入消息队列MessageQueue中,因为消息队列已经退出了。

需要注意的是Looper的quit方法从API Level 1就存在了,但是Looper的quitSafely方法从API Level 18才添加进来。

小例子:

package com.app;import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;public class MainActivity extends AppCompatActivity {private HandlerThread myHandlerThread ;private Handler handler ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//创建一个线程,线程名字:handler-threadmyHandlerThread = new HandlerThread( "handler-thread") ;//开启一个线程myHandlerThread.start();//在这个线程中创建一个handler对象handler = new Handler( myHandlerThread.getLooper() ){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);//这个方法是运行在 handler-thread 线程中的 ,可以执行耗时操作Log.d( "handler " , "消息: " + msg.what + "  线程: " + Thread.currentThread().getName()  ) ;}};//在主线程给handler发送消息handler.sendEmptyMessage( 1 ) ;new Thread(new Runnable() {@Overridepublic void run() {//在子线程给handler发送数据handler.sendEmptyMessage( 2 ) ;}}).start() ;}@Overrideprotected void onDestroy() {super.onDestroy();//释放资源myHandlerThread.quit() ;}
}

运行效果:

/com.app D/handler: 消息: 1  线程: handler-thread
/com.app D/handler: 消息: 2  线程: handler-thread

HandlerThread的特点

  • HandlerThread将loop转到子线程中处理,说白了就是将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。

  • 开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。HandlerThread本质是一个线程,在线程内部,代码是串行处理的。

  • 但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。

  • HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。

  • 对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。

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

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

相关文章

python 文件操作练习

1. 文件a.txt内容&#xff1a;每一行内容分别为商品名字&#xff0c;价钱&#xff0c;个数。 apple 10 3 tesla 100000 1 mac 3000 2 lenovo 30000 3 chicken 10 3 通过代码&#xff0c;将其构建成这种数据类型&#xff1a;[{name:apple,price:10,amount:3},{name:tesla,price:…

微软发布Enterprise Library 4.1和Unity 1.2

说明 微软模式与实践团队今天发布了Enterprise Library 4.1和Unity 1.2版本&#xff0c;这次发布的主要新特性如下&#xff1a; 1. 支持Visual Studio 2008 SP1 2. Unity应用程序块中加入了拦截机制 3. 性能提升 4. 配置工具的可用性提升 5. Bugs修复。 在Unity 1.2中有如下几点…

简易的波形折叠电路

01 波形折叠一、背景介绍今天在 Youtube 上看到 UP 主 Neukolln 展示了一款非常简单波形折叠电路。那么什么是波形折叠电路&#xff1f;它有什么用处&#xff1f;1、什么是波形折叠&#xff1f;通常情况下&#xff0c;信号在放大中会产生“饱和失真”&#xff0c;这是由于放大器…

STL 容器和迭代器连载6_顺序容器的操作3

2019独角兽企业重金招聘Python工程师标准>>> /*- * 文件名 &#xff1a;STL_con_ite_6.cpp * 开发人员&#xff1a;袁培荣 * 当前版本&#xff1a;1.0.0.2595 * 创建时间&#xff1a;2012-05-24 * 修改时间&#xff1a;2012-05-24 * 功能…

vector的内存释放

1. vector容器的内存自增长 与其他容器不同&#xff0c;其内存空间只会增长&#xff0c;不会减小。先来看看"C Primer"中怎么说&#xff1a;为了支持快速的随机访问&#xff0c;vector容器的元素以连续方式存放&#xff0c;每一个元素都紧挨着前一个元素存储。设想一…

poj 2096 , zoj 3329 , hdu 4035 —— 期望DP

题目&#xff1a;http://poj.org/problem?id2096 题目好长...意思就是每次出现 x 和 y&#xff0c;问期望几次 x 集齐 n 种&#xff0c;y 集齐 s 种&#xff1b; 所以设 f[i][j] 表示已经有几种&#xff0c;转移一下即可。 代码如下&#xff1a; #include<cstdio> #incl…

[C++]MySQL数据库操作实例

由于课程大实验需要使用c操作MySQL数据库&#xff0c;经过一番研究终于成功实现VS2008中与MySQL的连接。环境设置&#xff1a;安装完MySQL之后&#xff0c;将安装目录中的include目录下的libmysql.lib文件拷到VS2008安装目录中的VC\lib\下&#xff0c;然后在项目-选项-c/c-常规…

MapInfo开发心得——控件篇

前阵做一个项目过程中&#xff0c;需要结合MapInfo进行地方展示开发&#xff0c;积累一点点心得与大家共享以下所有基于MapXtreme 6.6MapInfo提供了足够强大的WinForm地图空间&#xff0c;可以很方便地在VS中拖拉摆放。但如此强大的控件也带来了封闭性太强的问题。现在我们都接…

89个嵌入式相关概念,你懂了几个?

嵌入式、计算机的学习&#xff0c;最基础的就是弄清一些概念。嵌入式、计算机相关的概念很多&#xff0c;这次汇总整理一些&#xff1a;1. 操作系统&#xff08;Operating System&#xff0c;OS&#xff09;&#xff1a;是管理计算机硬件与软件资源的系统软件&#xff0c;同时也…

使用VLC转码,在HTML5页面播放实时监控

首先要获取摄像机品牌的RTSP地址&#xff1a; 如大华的是rtsp://user:pwdip:port/cam/ realmonitor?channel1&subtype0 海康的是rtsp://user:pwdip:port/MPEG-4/ch1/main/av_stream Html5 <video>并不支持rtsp,所以使用vlc进行转码,将rtsp转http流,这样<video&g…

聊聊Linux中线程和进程的联系与区别!

大家好&#xff0c;推荐飞哥的一篇文章&#xff01;关于进程和线程&#xff0c;在 Linux 中是一对儿很核心的概念。但是进程和线程到底有啥联系&#xff0c;又有啥区别&#xff0c;很多人还都没有搞清楚。在网上对进程和线程的讨论中&#xff0c;很多都是聚集在这二位有啥不同。…

Docker swarm 实战-部署wordpress

Docker swarm 实战-部署wordpress 创建一个overlay的网络 docker network create -d overlay demo6imq8da3vcwvj2n499k4bwdlt docker network ls NETWORK ID NAME DRIVER SCOPE feea5ba8507b bridge bridge …

比GDB方便n倍的调试工具——CGDB

CGDB 是GDB的前端&#xff0c;在终端窗口中意图形化的形式来调试代码(基于ncurse)&#xff0c;非常方便。相对于GDB来说&#xff0c;可以很大的提高效率。这篇文章就来分享一下CGDB的最基本使用方法&#xff0c;如果是第一次听说&#xff0c;强烈建议您体验一下&#xff0c;一定…

WCF Security userName/Password

1. Transfer SecurityTransfer Security 主要包括三个方面&#xff1a; "消息完整性(Message Integrity)"、"消息机密性 (Message Confidentiality)" 和 "交互验证(Mutual Authentication)"。消息完整性必须确保消息在传输过程中没有被篡改&…

保护视力,我写的一个定时提醒的小玩意。

做程序员2年了&#xff0c;感觉视力越来越差。有时候常常工作到忘记休息。于是就想写一个能够定时提醒的小东西(公司不让从网络下载别的程序)。 功能: 1.能够每隔一段时间提醒我休息&#xff0c;做做眼保健操。 2.能够自己设定时间间隔. 运行环境&#xff1a;.ne…

WinCE程序的几种开发方法

文章允许转载,请注明出处和作者:luocq(akay_21cn_com)下面介绍的几种开发方法,还是倾向于Delphi的程序员,如果是熟练的VC程序员,当然VC是不二的选择.1、采用Delphi2007来进行WinCE .net程序开发http://spaces.msn.com/members/GordonLiWei/?partqsayear%3D2005%26amonth%3D12&…

几道Linux驱动相关面试题,你会几题?

1一、Linux基础1、任意3种网络操作的Linux命令,并说明他们的含义 1. ifconfig 命令ifconfig 用于查看和配置 Linux 系统的网络接口。 查看所有网络接口及其状态&#xff1a;ifconfig -a 。 使用 up 和 down 命令启动或停止某个接口&#xff1a;ifconfig eth0 up 和 ifconfig et…

解决Too many open files问题

转载&#xff1a;https://blog.csdn.net/zhuwinmin/article/details/72730288 当用linux做高并发服务器时&#xff0c;会遇到"Too many open files"的错误。 Linux是有文件句柄限制的&#xff08;open files&#xff09;&#xff0c;而且Linux默认不是很高&#xf…

树莓派的这十年

来源 | 新智元编辑 | 袁榭 好困刚刚过完10岁生日的树莓派&#xff0c;早已褪去了当年廉价电脑教具的外衣&#xff0c;一跃成为全球业界首屈一指的微型电脑品牌。为啥叫「Raspberry Pi」&#xff1f;从某种意义上讲&#xff0c;「树莓」这个命名方式其实很单纯&#xff0c;因为大…

layui 在springboot2.x 时,页面展示不了layui的问题

[[]]是thymeleaf的内联表达式&#xff0c;在script上加 th:inline"none" 即可 报错信息 转载于:https://www.cnblogs.com/SeaWxx/p/10287505.html