Android消息机制总结

53 篇文章 0 订阅
50 篇文章 0 订阅

先问几个问题

1.Handler消息处理机制

一个消息处理机制包括三个部分:发送消息,消息循环和处理消息

Handler:发送消息+处理消息

Looper:消息循环

MessageQueue:存储消息的数据结构+分发消息

具体源码不在这里分析。。。

2.ThreadLocal在Handler中的作用

一句话概况:存储线程私有的数据Looper对象

3.每个线程是否可以有多个handler,是否可以有多个Looper

多个handler:可以有多个Handler,他们使用的是同一个Looper对象。

多个Looper:一个线程处理消息时是线性处理的,线程是最基本的执行单位,不会再有并发处理的场景。所以一个线程拥有一个Looper对象,同时也对应一个消息队列。串行的执行着队列中的消息事件。
所以从线程本质来看:线程是没有必要拥有多个Looper对象的。一个Looper对象足矣。

4.消息延迟的底层实现原理

当sendMessage 时,enququeMessage()@MessageQueue 会将消息按照按照实际执行时间顺序(即msg.when)插入到队列

nextPollTimeoutMillis = (int)Math.min(msg.when - now, Interge.MAX_VALUE);

每次会重新计算阻塞的时间,时间到了之后,会唤醒主线程处理消息。

5.Handler导致的内存泄露问题处理

Handler的postDelayed()方法,该方法会将你的Handler装入一个Message,并把这条Message推到MessageQueue中,那么在你设定的delay到达之前,会有一条MessageQueue -> Message -> Handler -> Activity的链,导致你的Activity被持有引用而无法被回收。

6.Looper死循环

(1) Looper死循环为什么不会导致应用卡死?
对于线程即是一段可执行的代码,当可执行代码执行完成后,线程生命周期便该终止了,线程退出。而对于主线程,我们是绝不希望会被运行一段时间,自己就退出,那么如何保证能一直存活呢?简单做法就是可执行代码是能一直执行下去的,死循环便能保证不会被退出,例如,binder 线程也是采用死循环的方法,通过循环方式不同与 Binder 驱动进行读写操作,当然并非简单地死循环,无消息时会休眠。但这里可能又引发了另一个问题,既然是死循环又如何去处理其他事务呢?通过创建新线程的方式。真正会卡死主线程的操作是在回调方法 onCreate/onStart/onResume 等操作时间过长,会导致掉帧,甚至发生 ANR,looper.loop 本身不会导致应用卡死。
(2) 主线程的死循环一直运行是不是特别消耗 CPU 资源呢?
其实不然,这里就涉及到 Linux  pipe/epoll机制,简单说就是在主线程的 MessageQueue 没有消息时,便阻塞在 loop 的 queue.next() 中的 nativePollOnce() 方法里,此时主线程会释放 CPU 资源进入休眠状态,直到下个消息到达或者有事务发生,通过往 pipe 管道写端写入数据来唤醒主线程工作。这里采用的 epoll 机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。 所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源

参考:https://www.zhihu.com/question/34652589?sort=created

7.如何保证主线程一直运行,且不一直占用资源

死循环机制+Linux pipe/epoll机制

8.子线程中能更新UI吗

ViewRoot在主线程被创建,如果更新View的代码不在主线程执行的话,那么可能导致View内部绘制等其他逻辑中出现并发问题。 checkThread检查操作View的线程是否是创建View的线程,如上面的实现,在子线程创建的View,也只能在该子线程被访问,若在其他线程 访问,如主线程,仍然会抛出android.view.ViewRootImpl$CalledFromWrongThreadException。参考:
https://www.cnblogs.com/lao-liang/p/5108745.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值