避免内存抖动:共享内存池。
ActivityThread 的 main 函数不会退出,这是因为 Looper.loop
ActivityThread 扮演后台的角色,Looper.loop 扮演的是心跳的角色
Android 中 App 的所有事务都是 Message ,所以,当我们碰到异常的时候,看到的 Log 都是从 ActivityThread 中的 loop 处开始的
我们根据 Looper.loop 中打印日志的时间,来判断每个 Message 的执行耗时,这是 BlackCanary 的原理,能判断卡顿
没有 Msg 的时候,就休眠了,此时 ANR ?其实是混淆概念,这是2个事情, ANR 的含义是事务在定时范围内没有完成,执行事务前埋雷,执行完成后挖出雷,就不会爆炸;如果到了时间还没挖雷,雷就爆了。
什么是 epoll ?
上层有 n 个 I/O 事件,要如何才能去处理多个流。其实系统底层用一个线程死循环,去判断(多线程去判断更慢)。
epoll 与线程之间的数量没有对应关系,不用搞混。epoll 机制是需要注册的,要说明针对哪个事件去 阻塞和唤醒。
同步屏障(消息屏障)
屏障消息就是target 为 null 的消息。一般的消息都是通过 Handler 放到 MessageQuue 。消息有 3 种 :
- 同步消息
- 异步消息:async 标记为 true ,普通的同步msg 没人设置 async 标记
- 同步屏障消息
如果打印出 skip 30 frames ,the Application may be doing too many work …. 之类的错误,那就说明在主线程阻塞了,某个 msg 耗时过长,导致里面 30 个异步消未能执行。
在 ViewRootImpl 类的 scheduleTraversals 方法中,执行了 mHandler.getQueue().postSyncBarrier() 方法,在 MessageQueue 中添加了同步屏障。接着,在这个方法里面最终会执行到 performMeasure 、performLayout 和 performDraw 方法,这就很熟悉了,就是平时说view 绘制的步骤,或者说自定义View 尤其要关注的回调。
post 同步屏障的时候,会把屏障消息放到 MessageQueue 的最前面吗?不是的,只是普通的以当前时刻放入
一个线程一个 Looper 是由 static final 的 ThreadLocal 保证的,并且prepare 只能搞一次,第二次判断有 looper 的时候就报错了,不能多次 prepare 。