Open zhiyongyu opened 4 years ago
A: 线程是挂起了,为什么没有察觉是因为有nativeWake会唤醒他,主线程也是随时在挂起,阻塞的。 主线程接收的不光是我们发送的消息,还有系统的,比如安卓屏幕16.6ms刷新一次,就会不停的去唤醒这个主线程,当然还有其他的一些,比如输入法啊,系统广播啊等等这些。 所以在我们看来,界面是没有阻塞的。 TODO:nativeWake 和 nativePollOnce 的实现原理
B: 因为在ActivityThread的main方法中,启动了一个新的Binder线程(即ApplicationThread)用于接收系统服务发来的事件。 一些 Activity 生命周期的消息就是通过这个机制在循环外执行起来的。 比如一条暂停 Activity 的消息,首先是处于系统 system_server 进程的ActivityManagerService(AMS)线程调用 ApplicationThreadProxy(ATP)线程, 接着 ATP 线程通过 Binder 机制将消息传输到 APP 进程中的 ApplicationThread(AT)线程, 最后 AT 线程通过 Handler 消息机制,将消息发送到了主线程的消息队列中,主线程通过Looper.loop() 遍历得到该消息后,将消息分发给了 ActivityThread 对应的 Handler 中处理, 最后调用到了 Activity 的 onPause() 方法,方法处理完后,继续主线程继续循环下去。
C: MessageQueue不是队列,它内部使用一个Message链表实现消息的存和取。
D: 因为postDelay使用了SystemClock.uptimeMillis(),在手机进入休眠之后,将不会计时,比如设置的延时时间是500。但是在过了100之后手机进入休眠了,过了200之后重新退出休眠,那么实际上handler收到消息的时间是合计经过了700。延伸问题:如何解决这种问题?
A、messageQueue.next 是阻塞式的取消息, 如果有 delay 会调用 nativeWake; 那么问题来了, 线程挂起了, 是挂起的 UI线程吗? 答案是 YES, 为什么我没有察觉呢? 还有就是 nativeWake 和 nativePollOnce 的实现原理; B、looper.loop 既然是 while-true 为什么不会卡死? C、MessageQueue 是队列吗? 他是什么数据结构呢? D、handler 的postDelay, 时间准吗? 答案是不准, 为什么呢? E、handler 的 postDelay 的时间是 system.currentTime 吗? 答案是 NO, 你知道是什么吗? F、子线程run方法使用 handler 要先 looper.prepare(); 再 handler.post; 再 looper.loop(); G、handler 这么做到的 一个线程对应一个 looper, 答案是threadLocal, 你对ThreadLocal 有什么了解 吗? H、假设先 postDelay 10ms, 再postDelay 1ms, 你简单描述一下, 怎么处理这2条消息? I、你知道主线程的Looper, 第一次被调用loop方法, 在什么时候吗? 哪一个类 J、你对 IdleHandler 有多少了解? K、你了解 HandlerThread 吗? L、你对 Message.obtain() 了解吗, 或者你知道 怎么维护消息池吗