Android HandlerThread的使用及原理详解
发布时间 - 2026-01-11 00:22:03 点击率:次一、HandlerThread的含义

HandlerThread能够新建拥有Looper的线程。这个Looper能够用来新建其他的Handler。(线程中的Looper)需要注意的是,新建的时候需要被回调。
二、HandlerThread的用法
一般情况下,我们会经常用Handler在子线程中更新UI线程,那是因为在主线程中有Looper循环,而HandlerThread新建拥有Looper的子线程又有什么用呢?
必然是执行耗时操作。举个例子,数据实时更新,我们每10秒需要切换一下显示的数据,如果我们将这种长时间的反复调用操作放到UI线程中,虽说可以执行,但是这样的操作多了之后,很容易会让UI线程卡顿甚至崩溃。
于是,就必须在子线程中调用这些了。
HandlerThread继承自Thread,一般适应的场景,便是集Thread和Handler之所长,适用于会长时间在后台运行,并且间隔时间内(或适当情况下)会调用的情况,比如上面所说的实时更新。
三、实现每2秒更新一下UI
public class MainActivity extends AppCompatActivity {
private TextView tvMain;
private HandlerThread mHandlerThread;
//子线程中的handler
private Handler mThreadHandler;
//UI线程中的handler
private Handler mMainHandler = new Handler();
//以防退出界面后Handler还在执行
private boolean isUpdateInfo;
//用以表示该handler的常熟
private static final int MSG_UPDATE_INFO = 0x110;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvMain = (TextView) findViewById(R.id.tv_main);
initThread();
}
private void initThread()
{
mHandlerThread = new HandlerThread("check-message-coming");
mHandlerThread.start();
mThreadHandler = new Handler(mHandlerThread.getLooper())
{
@Override
public void handleMessage(Message msg)
{
update();//模拟数据更新
if (isUpdateInfo)
mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
}
};
}
private void update()
{
try
{
//模拟耗时
Thread.sleep(2000);
mMainHandler.post(new Runnable()
{
@Override
public void run()
{
String result = "每隔2秒更新一下数据:";
result += Math.random();
tvMain.setText(result);
}
});
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
@Override
protected void onResume()
{
super.onResume();
//开始查询
isUpdateInfo = true;
mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
}
@Override
protected void onPause()
{
super.onPause();
//停止查询
//以防退出界面后Handler还在执行
isUpdateInfo = false;
mThreadHandler.removeMessages(MSG_UPDATE_INFO);
}
@Override
protected void onDestroy()
{
super.onDestroy();
//释放资源
mHandlerThread.quit();
}
}
四、HandlerThread 原理
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
首先我们可以看到HandlerThread继承自Thread,因此在run()中的逻辑都是在子线程中运行的。
接下来就是两个关键的方法,run()和getLooper():
run()中可以看到是很简单的创建Looper以及让Looper工作的逻辑。
run()里面当mLooper创建完成后有个notifyAll(),getLooper()中有个wait(),这有什么用呢?因为的mLooper在一个线程中执行创建,而我们的handler是在UI线程中调用getLooper()初始化的。
也就是说,我们必须等到mLooper创建完成,才能正确的返回。getLooper();wait(),notify()就是为了解决这两个线程的同步问题。
# Android
# HandlerThread
# 深入Android HandlerThread 使用及其源码完全解析
# Android实例HandlerThread源码分析
# 实例分析Android中HandlerThread线程用法
# Android HandlerThread使用方法详解
# Android用HandlerThread模拟AsyncTask功能(ThreadTask)
# android使用handlerthread创建线程示例
# Android HandlerThread案例详解
# 是在
# 有个
# 还在
# 可以看到
# 什么用
# 的是
# 常熟
# 中有
# 又有
# 其他的
# 长时间
# 适用于
# 很容易
# 这两个
# 时间内
# 很简单
# 会让
# 我们必须
# 每隔
# 那是因为
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何快速生成高效建站系统源代码?
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
node.js报错:Cannot find module 'ejs'的解决办法
Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】
如何用PHP快速搭建高效网站?分步指南
海南网站制作公司有哪些,海口网是哪家的?
Laravel如何优化应用性能?(缓存和优化命令)
活动邀请函制作网站有哪些,活动邀请函文案?
做企业网站制作流程,企业网站制作基本流程有哪些?
iOS发送验证码倒计时应用
利用python获取某年中每个月的第一天和最后一天
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?
教你用AI润色文章,让你的文字表达更专业
专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?
动图在线制作网站有哪些,滑动动图图集怎么做?
高端建站三要素:定制模板、企业官网与响应式设计优化
原生JS获取元素集合的子元素宽度实例
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
如何为不同团队 ID 动态生成多个“认领值班”按钮
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
常州企业网站制作公司,全国继续教育网怎么登录?
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
如何快速打造个性化非模板自助建站?
Firefox Developer Edition开发者版本入口
java中使用zxing批量生成二维码立牌
详解CentOS6.5 安装 MySQL5.1.71的方法
laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程
如何在新浪SAE免费搭建个人博客?
如何在云虚拟主机上快速搭建个人网站?
如何在云服务器上快速搭建个人网站?
高端网站建设与定制开发一站式解决方案 中企动力
详解阿里云nginx服务器多站点的配置
Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程
黑客如何通过漏洞一步步攻陷网站服务器?
如何有效防御Web建站篡改攻击?
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
Linux后台任务运行方法_nohup与&使用技巧【技巧】
js实现点击每个li节点,都弹出其文本值及修改
Laravel PHP版本要求一览_Laravel各版本环境要求对照
谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程
Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
如何批量查询域名的建站时间记录?
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案

