Handler
是 Android
中用来更新UI 的一套消息处理机制。Handler
允许线程间发送Message
或Runnable
对象进行通信。在Android
中UI修改只能通过UI Thread
,子线程不能更新UI
。如果子线程想更新UI
,需要通过 Handler
发送消息给主线程,进而达到更新UI
的目的。
本篇文章主要介绍 Android
开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:
- Handler 消息处理机制原理
- Handler 机制处理的4个关键对象
- Handler常用方法
- 子线程更新UI 异常处理
- 主线程给子线程发送消息的方法
- 子线程给主线程发送消息的方法
- 主、子 线程 互发消息方法
- 子线程方法中调用主线程更新UI的方法
欢迎关注微信公众号:程序员Android
公众号ID:ProgramAndroid
获取更多信息
![](https://img.haomeiwen.com/i5851256/d53a800648e23670.jpg)
我们不是牛逼的程序员,我们只是程序开发中的垫脚石。
我们不发送红包,我们只是红包的搬运工。
Handler 简介
继承关系如下:
java.lang.Object
↳ android.os.Handler
1. Handler 消息处理机制原理
当Android
应用程序创建的时候,系统会给每一个进程提供一个Looper
,Looper
是一个死循环,它内部维护一个消息队列,Looper
不停的从消息队列中取Message
,取到的消息就发送给handler
,最后Handler
根据接收的消息去修改UI
等。
2. Handler 机制处理的4个关键对象
1.Message
线程之间传递的消息,可以携带一些简单的数据供子线程与主线程进行交换数据。
2.Message Queue
存放通过Handler
发送的Message
的消息队列,每一个线程只有一个消息队列。
3.Handler
消息处理者,主要用于发送跟处理消息。
主要功能:
发送消息SendMessage()
处理消息 HandleMessage()
4.Looper
内部包含一个死循环的MessageQueue
,用于存储handler
发送的Message
,Looper
则是不断的从消息队列中取消,如果有消息就取出发送给Handler
处理,没有则阻塞。
总结:
Handler
负责发送Message
到Message Queue
,Looper
负责从Message Queue
遍历Message
,然后直接把遍历的消息回传给Handler
自己,通过Handler
自身的handleMessage
处理更新UI
等操作。
![](https://img.haomeiwen.com/i5851256/dfc1b5ecf2d4b4aa.png)
3. Handler常用方法
1.Runnable对象
- post(Runnable)
使用方法举例:
![](https://img.haomeiwen.com/i5851256/870f9968798b3332.png)
- postAtTime(Runnable, long)
- postDelayed(Runnable, long)
2. Message 对象
- sendEmptyMessage(int)
使用方法举例:
![](https://img.haomeiwen.com/i5851256/0b76778d4cda08a1.png)
- sendMessage(Message)
使用方法举例:
![](https://img.haomeiwen.com/i5851256/08250402c9ca777f.png)
- sendMessageAtTime(Message, long),
- sendMessageDelayed(Message, long)
3.接收、处理Message
- handleMessage(Message)
使用方法举例:
![](https://img.haomeiwen.com/i5851256/f80bd03781896260.png)
4. 子线程更新UI 异常处理
子线程不能更新UI
,如果在子线程中更新UI
,会出现CalledFromWrongThreadException
异常。
- CalledFromWrongThreadException
![](https://img.haomeiwen.com/i5851256/07c6bfaacf607a17.png)
解决方法:
子线程通过Handler
发送消息给主线程,让主线程处理消息,进而更新UI
。
5. 主线程给子线程发送消息的方法
此例子中子线程通过Looper
不断遍历主线程发送的消息,Looper
使用方法如下:
- 准备Looper 轮询器
Looper.prepare();
- Handler 处理遍历消息
Handler mHandler = new Handler()
- 遍历消息队列
Looper.loop();
Looper
使用方法如下:
![](https://img.haomeiwen.com/i5851256/2fd912829fe7ec6f.png)
主线程发送消息给子线程 的使用例子如下:
![](https://img.haomeiwen.com/i5851256/7386602af632f6fe.jpg)
6. 子线程给主线程发送消息的方法
子线程发送消息给主线程方法
![](https://img.haomeiwen.com/i5851256/340b352f4f498533.png)
![](https://img.haomeiwen.com/i5851256/e7365b76d415d1de.png)
7. 主、子 线程 互发消息方法
主要实现主、子线程每隔1s中通信一次
- 实现打印
Log
如下:
![](https://img.haomeiwen.com/i5851256/8a2b63b8486ddd1a.png)
- 实现方法如下:
![](https://img.haomeiwen.com/i5851256/313da65a5df7769e.png)
![](https://img.haomeiwen.com/i5851256/9f28fb7c68357e07.png)
8.子线程方法中调用主线程更新UI的方法
Activity 中 可以使用 runOnUiThread(Runnable)
![](https://img.haomeiwen.com/i5851256/c990acb33cce19d7.png)
子线程使用 Handler.post(Runnable)
![](https://img.haomeiwen.com/i5851256/c2dd622b26593504.png)
View.post()
![](https://img.haomeiwen.com/i5851256/e639982f88ac8061.png)
Handler.sendMessage(Message)
![](https://img.haomeiwen.com/i5851256/313da65a5df7769e.png)
至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。期待您的关注,
感谢您的阅读,谢谢!
欢迎关注微信公众号:程序员Android
公众号ID:ProgramAndroid
获取更多信息
![](https://img.haomeiwen.com/i5851256/d53a800648e23670.jpg)
我们不是牛逼的程序员,我们只是程序开发中的垫脚石。
我们不发送红包,我们只是红包的搬运工。
![](https://img.haomeiwen.com/i5851256/5e84a53c45b560d2.gif)
点击阅读原文,获取更多福利
![](https://img.haomeiwen.com/i5851256/4ade7bb7659b1047.gif)
网友评论