Android-基础-Handler:机制、原理与示例
Android Handler机制、原理与示例 基本示例创建与使用主线程 Handlerpublic class MainActivity extends AppCompatActivity {private Handler mHandler;private TextView mTextView;Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView findViewById(R.id.text_view); // 在主线程创建 Handler mHandler new Handler(Looper.getMainLooper()) { Override public void handleMessage(NonNull Message msg) { switch (msg.what) { case 1: mTextView.setText(收到消息 msg.obj); break; } } }; // 启动子线程发送消息 new Thread(new Runnable() { Override public void run() { try { Thread.sleep(2000); Message msg Message.obtain(); msg.what 1; msg.obj 来自子线程的消息; mHandler.sendMessage(msg); // 或使用便捷方式 mHandler.post(() - { mTextView.setText(通过 post 更新 UI); }); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); }}创建与使用子线程 Handlerpublic class MainActivity extends AppCompatActivity {private HandlerThread handlerThread;private Handler handler;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 创建 HandlerThread handlerThread new HandlerThread(MyHandlerThread); handlerThread.start(); // 创建 Handler关联到 HandlerThread 的 Looper handler new Handler(handlerThread.getLooper()) { Override public void handleMessage(Message msg) { // 在子线程执行 Log.d(Handler, 处理消息: msg.what); } }; // 发送任务 handler.post(new Runnable() { Override public void run() { // 在 HandlerThread 中执行 Log.d(Handler, 执行任务); } });}Overrideprotected void onDestroy() {super.onDestroy();// 退出消息循环if (handlerThread ! null) {handlerThread.quitSafely();}}}// 创建子线程new Thread(new Runnable() {Overridepublic void run() {// 1. 初始化 LooperLooper.prepare();// 2. 创建 Handler Handler handler new Handler(Looper.myLooper()) { Override public void handleMessage(Message msg) { // 处理消息 Log.d(Handler, 收到消息: msg.what); } }; // 3. 启动消息循环 Looper.loop(); }}).start();定时任务示例// 延迟执行mHandler.postDelayed(() - {Log.d(“Handler”, “3秒后执行”);}, 3000);// 循环执行private Runnable mUpdateTask new Runnable() {Overridepublic void run() {updateUI();// 每1秒执行一次mHandler.postDelayed(this, 1000);}};// 开始循环mHandler.post(mUpdateTask);// 停止循环重要防止内存泄漏Overrideprotected void onDestroy() {super.onDestroy();mHandler.removeCallbacks(mUpdateTask);}说明.获取looper的方式Looper.getMainLooper()始终返回主线程的 LooperLooper.myLooper()获取当前线程的 Looper可能返回 nullhandler.getLooper()handlerThread.getLooper().一个handler对应一个Looper一个Looper可以对应多个handler 核心机制Handler 四件套┌─────────────────────────────────────────┐│ MessageQueue消息队列 ││ ┌─────────────┬─────────────┐ ││ │ Message1 │ Message2 │ … ││ └─────────────┴─────────────┘ │└─────────────┬──────────────────────────┘│┌─────────────▼──────────────────────────┐│ Looper消息循环器 ││ • 从 MessageQueue 取出消息 ││ • 分发给对应的 Handler │└─────────────┬──────────────────────────┘│┌─────────────▼──────────────────────────┐│ Handler消息处理器 ││ • 发送消息到 MessageQueue ││ • 处理 Looper 分发的消息 │└─────────────┬──────────────────────────┘│┌─────────────▼──────────────────────────┐│ Message消息 ││ • what: 消息标识 ││ • arg1/arg2: 整型参数 ││ • obj: 对象参数 ││ • target: 目标 Handler │└────────────────────────────────────────┘ 工作原理消息循环流程// Looper.loop() 简化逻辑public static void loop() {final Looper me myLooper();final MessageQueue queue me.mQueue;for (;;) { // 1. 从队列取消息可能阻塞 Message msg queue.next(); if (msg null) return; // 2. 分发给目标 Handler msg.target.dispatchMessage(msg); // 3. 回收消息到池中 msg.recycleUnchecked(); }}消息发送与处理// Handler.sendMessage() 流程public boolean sendMessage(Message msg) {return sendMessageDelayed(msg, 0);}public boolean sendMessageDelayed(Message msg, long delayMillis) {// 设置消息的目标 Handlermsg.target this;// 计算执行时间 if (delayMillis 0) delayMillis 0; long when SystemClock.uptimeMillis() delayMillis; // 入队 return queue.enqueueMessage(msg, when);}// 消息分发public void dispatchMessage(Message msg) {if (msg.callback ! null) {// 处理 RunnablehandleCallback(msg);} else {if (mCallback ! null) {if (mCallback.handleMessage(msg)) return;}// 调用 handleMessage()handleMessage(msg);}}⚙️ 关键技术点线程绑定// 主线程 Looper 初始化ActivityThread.main()public static void main(String[] args) {Looper.prepareMainLooper(); // 创建主线程 LooperActivityThread thread new ActivityThread();thread.attach(false);if (sMainThreadHandler null) { sMainThreadHandler thread.getHandler(); } Looper.loop(); // 开启消息循环 throw new RuntimeException(Main thread loop unexpectedly exited);}// 子线程使用 Handlernew Thread(() - {// 1. 准备 LooperLooper.prepare();// 2. 创建 Handler会自动绑定当前线程的 Looper Handler handler new Handler() { Override public void handleMessage(Message msg) { // 处理消息 } }; // 3. 开启循环 Looper.loop();}).start();消息池优化// 消息池避免频繁创建对象Message msg Message.obtain(); // 推荐从池中获取// vsMessage msg new Message(); // 不推荐每次创建新对象// 使用后系统自动回收msg.recycleUnchecked();同步屏障Sync Barrier// 紧急消息处理public int postSyncBarrier() {return mQueue.postSyncBarrier(SystemClock.uptimeMillis());}// 异步消息优先级更高msg.setAsynchronous(true);mHandler.sendMessage(msg); 注意事项内存泄漏处理// 错误示例匿名内部类持有 Activity 引用private Handler mHandler new Handler() {Overridepublic void handleMessage(Message msg) {// 持有外部类引用}};// 正确示例1静态内部类 弱引用private static class SafeHandler extends Handler {private final WeakReference mActivity;public SafeHandler(Activity activity) { mActivity new WeakReference(activity); } Override public void handleMessage(Message msg) { Activity activity mActivity.get(); if (activity ! null !activity.isFinishing()) { // 安全操作 } }}// 正确示例2在 onDestroy 中清理Overrideprotected void onDestroy() {super.onDestroy();mHandler.removeCallbacksAndMessages(null);}跨线程通信// 子线程 → 主线程new Thread(() - {// 耗时操作String result doBackgroundWork();// 方式1sendMessage Message msg Message.obtain(mainHandler); msg.obj result; mainHandler.sendMessage(msg); // 方式2post更简洁 mainHandler.post(() - updateUI(result)); // 方式3runOnUiThreadActivity 中 runOnUiThread(() - updateUI(result));}).start();HandlerThread 使用// 创建自带 Looper 的工作线程HandlerThread handlerThread new HandlerThread(“WorkerThread”);handlerThread.start();// 获取该线程的 HandlerHandler workerHandler new Handler(handlerThread.getLooper());// 在工作线程执行任务workerHandler.post(() - {// 在 WorkerThread 中执行doHeavyWork();// 完成后通知主线程 mainHandler.post(() - updateUI());});// 结束时清理handlerThread.quitSafely(); 性能优化建议消息复用使用 Message.obtain() 而非 new Message()及时清理在合适的生命周期移除回调避免过度使用简单的定时任务可用 postDelayed复杂调度考虑 RxJava 或 Coroutine线程管理使用 HandlerThread 管理后台线程的 Looper同步屏障谨慎用只在必要时使用异步消息这种机制使得 Android 能够实现高效、安全的线程间通信是 Android 异步编程的基石。

相关新闻

终端结构优化——沟槽场限环的仿真设计与性能验证

终端结构优化——沟槽场限环的仿真设计与性能验证

1. 沟槽场限环的基本原理与设计挑战在高压功率器件中,终端结构的设计直接影响器件的击穿电压和可靠性。传统场限环(FLR)通过P型掺杂环分散主结边缘电场,但受限于离子注入工艺,结深通常较浅(约6-8μm&#x…

2026/7/15 8:06:17 阅读更多 →
深入解析TI CC2564C蓝牙芯片:从射频性能到辅助模式实战

深入解析TI CC2564C蓝牙芯片:从射频性能到辅助模式实战

1. 项目概述:为什么需要深入理解一颗蓝牙芯片?如果你正在设计一款需要蓝牙功能的嵌入式设备,比如无线耳机、智能家居传感器或者工业遥控器,选型时面对琳琅满目的芯片,是不是常常感到无从下手?是选一个集成度…

2026/7/15 8:04:16 阅读更多 →
C++ Web开发新思路:Wt框架无JavaScript架构解析与实践指南

C++ Web开发新思路:Wt框架无JavaScript架构解析与实践指南

1. 为什么选择C来写Web应用?聊聊Wt框架的独特定位如果你是一个长期和C打交道的开发者,当听到“用C写Web应用”这个说法时,第一反应可能是疑惑甚至抗拒。毕竟,这个领域早已是JavaScript、Python、Java乃至Go的天下,Node…

2026/7/15 7:54:11 阅读更多 →

最新新闻

LaTeX实战:从TexLive/TexStudio安装到参考文献引用的全流程避坑指南

LaTeX实战:从TexLive/TexStudio安装到参考文献引用的全流程避坑指南

1. 为什么选择LaTeX?学术写作的终极解决方案 第一次接触LaTeX时,我和大多数新手一样充满疑惑——为什么放着简单的Word不用,非要折腾这个看似复杂的排版系统?直到我的导师要求修改论文第20版的公式编号时,我才真正明白…

2026/7/15 8:48:36 阅读更多 →
Jido内存管理指南:Agent、Plugin和Space内存模型

Jido内存管理指南:Agent、Plugin和Space内存模型

Jido内存管理指南:Agent、Plugin和Space内存模型 【免费下载链接】jido 🤖 Autonomous agent framework for Elixir. Built for distributed, autonomous behavior and dynamic workflows. 项目地址: https://gitcode.com/GitHub_Trending/ji/jido …

2026/7/15 8:48:36 阅读更多 →
Money库与数据库集成:如何在MySQL和PostgreSQL中存储货币值

Money库与数据库集成:如何在MySQL和PostgreSQL中存储货币值

Money库与数据库集成:如何在MySQL和PostgreSQL中存储货币值 【免费下载链接】money Value Object that represents a monetary value (using a currencys smallest unit). 项目地址: https://gitcode.com/gh_mirrors/money3/money 在开发金融或电商类应用时&…

2026/7/15 8:48:36 阅读更多 →
AI竞赛中的威胁叙事策略与中美科研经费博弈分析

AI竞赛中的威胁叙事策略与中美科研经费博弈分析

这次我们来看一个关于AI竞赛中"威胁叙事"策略的分析,特别是中美科研经费博弈这个热点话题。这个话题最近在技术圈和投资圈都很受关注,因为它直接关系到AI发展的资源分配和技术路线选择。所谓"威胁叙事",简单说就是通过强…

2026/7/15 8:46:34 阅读更多 →
聚焦:ISO 14644-21:2023《洁净室悬浮粒子采样》如何优化制药环境监测?

聚焦:ISO 14644-21:2023《洁净室悬浮粒子采样》如何优化制药环境监测?

1. ISO 14644-21:2023标准的核心升级点 2023年发布的ISO 14644-21标准,专门针对洁净室悬浮粒子采样技术进行了全面优化。相比2015版,这次更新可不是简单的小修小补,而是从采样设备选择到操作流程都做了重大调整。我在药厂环境监测一线干了八年…

2026/7/15 8:44:34 阅读更多 →
【NI-RIO实战】从确定性到可靠性:构建工业级实时控制系统的核心要素

【NI-RIO实战】从确定性到可靠性:构建工业级实时控制系统的核心要素

1. 工业级实时控制系统的核心挑战 在自动化生产线或电力系统监控这类场景中,一个控制指令延迟1毫秒可能导致设备碰撞或电网故障。我曾参与过某汽车焊接机器人的改造项目,原系统因Windows的随机延迟导致焊枪定位偏差超过0.5mm,最终不得不改用N…

2026/7/15 8:40:33 阅读更多 →

日新闻

YOLO11 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

YOLO11 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

前言 本文介绍了面向红外小目标检测的时空特征融合模块——STFFM,用于增强复杂背景下目标与噪声、杂波的区分能力。该方法通过拼接空间特征与时间/运动特征,并结合通道注意力、空间注意力和残差增强机制,实现对关键语义通道与疑似目标区域的…

2026/7/15 0:01:00 阅读更多 →
YOLO26 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

YOLO26 改进 - 特征融合 | STFFM空间时间特征融合模块,强化时空互补、抑制噪声,助力小目标检测高效涨点

前言 本文介绍了面向复杂背景小目标检测的时空特征融合模块——STFFM。该模块通过空间分支与时间/运动分支的特征拼接,引入通道注意力和空间注意力对融合特征进行自适应筛选,并结合残差增强与通道压缩,突出目标区域、抑制背景噪声。我们将 S…

2026/7/15 0:01:00 阅读更多 →
行星减速机为什么能提高扭矩?从功率守恒到输出扭矩校核

行星减速机为什么能提高扭矩?从功率守恒到输出扭矩校核

一、为什么减速以后扭矩会增大 旋转机械的功率、转速和扭矩之间存在以下关系: T 9550 P n 其中: T为扭矩,单位Nm; P为功率,单位kW; n为转速,单位r/min。 在功率基本不变的情况下:…

2026/7/15 0:03:00 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/14 16:53:23 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/14 14:00:13 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/14 7:15:24 阅读更多 →

月新闻