宝宝们,现在会说Handler流程已经out了,面试官不会止于此的,他会问
handler是如何切换线程的呢?
handler的Looper是死循环获取消息队列的消息,为什么不会阻塞主线程呢?
handler延时消息怎样处理?
上干货!!!
handler是如何切换线程的呢?
1.handler在其他线程发送Message时,如调用sendMessage(),会创建一个Message信息,注意这个Message持有一个Handler引用的。
2.Message加入到MessageQueue中是调用了handler的enqueue。
3.之后Message被Looper从MessageQueue取出,注意这个Looper是当前线程的Looper。确切的说一个线程持有一个Looper,这个Looper存放在线程的ThreadLocal中,ThreadLocal只存一个Looper,所有线程、ThreadLocal、Looper是一一对应的。
4.Looper拿到Message,交给Message所持有的handler的dispatchMessage()处理,这时Message以参数的形式,存在在当前线程了。
handler的Looper是死循环获取消息队列的消息,为什么不会阻塞主线程呢?
1.线程是一段可执行的代码,执行完成之后,什么周期就该终止了。
2.Android主线程,我们不希望它执行完就退出,我们希望他一直存在。所以使用在ActivityThread创建Looer,以及调用Looper.loop使用死循环保证主线程不会退出。
3.导致ANR是因为在Activity的生命周期方法中加载了耗时操作,按键是5秒、广播10秒、服务20秒,超时将导致出现ANR。
handler延时消息怎样处理?
handler发送消息最终都会调用sendMessageDelayed(),计算出真正执行的时间后调用sendMessageAtTime(),然后加入到队列中enqueueMessage,Looper中的next(), 获取下次唤醒的时间,来处理Message。