副标题[/!--empirenews.page--]
我们在日常开发中,总是不可避免的会用到 Handler,虽说 Handler 机制并不等同于 Android 的消息机制,但 Handler 的消息机制在 Android 开发中早已谙熟于心,非常重要!

通过本文,你可以非常容易得到一下问题的答案:
- Handler、Looper、Message 和 MessageQueue 的原理以及它们之间的关系到底是怎样的?
- MessageQueue 存储结构是什么?
- 子线程为啥一定要调用 Looper.prepare() 和 Looper.loop()?
Handler 的简单使用
相信应该没有人不会使用 Handler 吧?假设在 Activity 中处理一个耗时任务,需要更新 UI,简单看看我们平时是怎么处理的。
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main3)
- // 请求网络
- subThread.start()
- }
- override fun onDestroy() {
- subThread.interrupt()
- super.onDestroy()
- }
- private val handler by lazy(LazyThreadSafetyMode.NONE) { MyHandler() }
- private val subThread by lazy(LazyThreadSafetyMode.NONE) { SubThread(handler) }
- private class MyHandler : Handler() {
- override fun handleMessage(msg: Message) {
- super.handleMessage(msg)
- // 主线程处理逻辑,一般这里需要使用弱引用持有 Activity 实例,以免内存泄漏
- }
- }
- private class SubThread(val handler: Handler) : Thread() {
- override fun run() {
- super.run()
- // 耗时操作 比如做网络请求
- // 网络请求完毕,咱们就得哗哗哗通知 UI 刷新了,直接直接考虑 Handler 处理,其他方案暂时不做考虑
- // 第一种方法,一般这个 data 是请求结果解析的内容
- handler.obtainMessage(1,data).sendToTarget()
- // 第二种方法
- val message = Message.obtain() // 尽量使用 Message.obtain() 初始化
- message.what = 1
- message.obj = data // 一般这个 data 是请求结果解析的内容
- handler.sendMessage(message)
- // 第三种方法
- handler.post(object : Thread() {
- override fun run() {
- super.run()
- // 处理更新操作
- }
- })
- }
- }
上述代码非常简单,因为网络请求是一个耗时任务,所以我们新开了一个线程,并在网络请求结束解析完毕后通过 Handler 来通知主线程去更新 UI,简单采用了 3 种方式,细心的小伙伴可能会发现,其实第一种和第二种方法是一样的。就是利用 Handler 来发送了一个携带了内容 Message 对象,值得一提的是:我们应该尽可能地使用 Message.obtain() 而不是 new Message() 进行 Message 的初始化,主要是 Message.obtain() 可以减少内存的申请。
受到大家在前面文章提出的建议,我们就尽量地少贴一些源码了,大家可以直接很容易发现,上述的所有方法最终都会调用这个方法:
- public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
- MessageQueue queue = mQueue;
- if (queue == null) {
- RuntimeException e = new RuntimeException(
- this + " sendMessageAtTime() called with no mQueue");
- Log.w("Looper", e.getMessage(), e);
- return false;
- }
- return enqueueMessage(queue, msg, uptimeMillis);
- }
- private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
- msg.target = this;
- if (mAsynchronous) {
- msg.setAsynchronous(true);
- }
- return queue.enqueueMessage(msg, uptimeMillis);
- }
上面的代码出现了一个 MessageQueue,并且最终调用了 MessageQueue#enqueueMessage 方法进行消息的入队,我们不得不简单说一下 MessageQueue 的基本情况。
MessageQueue
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|