第十章 Android的消息机制

一、Android消息机制的作用
Android的消息机制主要是指Handler的运行机制,它的作用是提供”在某个具体的线程中执行任务”的功能。

二、Android消息机制在更新UI上的应用
Android只能在主线程中访问UI,因为Android的UI控件不是线程安全的。为什么不加入锁机制呢?因为那样会降低UI访问效率。
可是有时候要进行耗时操作,主线程又不能进行耗时操作,不然会ANR。这时候我们就要开启子线程进行耗时操作。
在子线程耗时操作完成后,要更新UI,这时候就要用到消息机制回到主线程了。

三、Android消息机制的具体实现
1、ThreadLocal
当某些数据是以线程为作用域并且不同线程拥有不同副本的时候,就可以考虑使用ThreadLocal。
我们在不同的线程往ThreadLocal里放入一个对象,那么在不同的线程里拿取对象时,拿到的就是专属于这个线程的对象。
比如对于Handler来说,它需要获取当前线程的Looper,很显然Looper的作用域就是线程并且不同线程具有不同的Looper,这个时候通过ThreadLocal就可以轻松实现Looper在线程中的存取。
Looper只需要在自己的线程中工作,不需要在别的线程中引用。

ThreadLocal的使用:
这里写图片描述

2、在特定的线程里处理消息
我们首先需要在一个线程里初始化Looper,并开始循环取消息

Looper.prepare();
Looper.loop();

初始化Looper的时候也就初始化了一个MessageQueue
这里写图片描述
loop()会调用MessageQueue的next()来获取新消息,而next()是一个阻塞操作,当没有消息时,next会一直阻塞在那里。如果MessageQueue的next()返回了新消息,Looper就会处理这条消息。msg.target.dispatchMessage(msg),这里的msg.target就是发送这条消息的Handler对象,这样Handler发送的消息最终又交给它的dispatchMessage()处理了。而loop()方法是运行在调用loop()方法的线程里,所以就将要做的任务切换到这个线程中来了。

3、向特定的线程发消息

这里写图片描述
在一个线程中初始化Handler时,会取出当前线程的Looper对象让Handler持有,从而Handler持有这个Looper的MessageQueue对象,从而Handler能够调用MessageQueue的enqueueMessage(),向MessageQueue中添加消息。

4、Handler处理消息的过程
这里写图片描述

当message有回调时,就先执行回调,没有的话就不执行;
然后如果有CallBack接口,就先调用Handler的CallBack接口的处理方法,如果它表示已经处理完毕,那么就不会往下继续处理了;
然后调用Handler的处理方法

这里写图片描述

5、如何退出Looper
Looper也是可以退出的,Looper提供了quit和quitSafely来退出一个Looper,二者的区别是:quit会直接退出Looper,而quitSafely只是设定一个退出标记,然后把消息队列中的已有消息处理完毕后才安全退出。Looper退出后,通过Handler发送的消息会失败,这个时候Handler的send方法会返回false。
loop方法是一个死循环,唯一跳出循环的方式是MessageQueue的next方法返回了null。当looper的quit方法被调用时,Looper就会调用MessageQueue的quit或者quitSafely方法来通知消息队列退出,当消息队列被标记为退出状态时,它的next方法就会返回null。


这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值