Android秒表应用中runTimer的postDelayed为何未阻塞onStart调用?
问题解答
核心原因是你混淆了同步阻塞循环和Handler异步消息调度的逻辑,具体原理如下:
- Android主线程从应用启动时就会绑定
Looper,内部维持一个死循环轮询MessageQueue消息队列,所有主线程的操作(包括Activity生命周期回调、UI更新、你通过Handler提交的Runnable任务)都会被封装成消息存入队列,由Looper按顺序取出执行。 - 你在
runTimer()方法中调用handler.post(Runnable)时,只是把Runnable任务封装成消息插入到当前消息队列的末尾,不会同步执行这个Runnable,post方法插入完消息就会直接返回,runTimer()也就执行完毕,onCreate()可以正常走完后续逻辑,完全不会被阻塞。 - 等
onCreate、onStart这些优先级更高的生命周期消息都执行完成后,Looper才会从队列中取出你之前提交的Runnable执行。执行过程中完成UI更新后,调用handler.postDelayed(this, 1000)也只是向Looper注册一个延时任务:1000毫秒后再把这个Runnable插入消息队列,这行代码执行完当前Runnable的run方法就结束了,主线程会被释放处理其他任务,不会一直占用。 - 你感知到的“无限循环”是靠每次执行完任务再提交下一个延时任务实现的,不是同步写
while(true)这类死循环阻塞主线程,自然不会影响后续生命周期方法的调用。
内容的提问来源于stack exchange,提问作者Darshil Shah
相关产品推荐
相关产品推荐

