为什么Looper.loop()死循环不会导致ANR
2018-02-28 07:47
471 查看
为什么loop这个死循环会在主线程执行,不会ANR么?
答:最开始Android的入口ActivityThread里面的main方法,里面有一个巨大的Handler,然后会创建一个主线程的looper对象,这也是为什么直接在主线程拿Handler就有Looper的原因,在其他线程是要自己Looper.prepare()的。
其实整个Android就是在一个Looper的loop循环的,整个Android的一切都是以Handler机制进行的,即只要有代码执行都是通过Handler来执行的,而所谓ANR便是Looper.loop没有得到及时处理,一旦没有消息,Linux的epoll机制则会通过管道写文件描述符的方式来对主线程进行唤醒与沉睡,Android里调用了linux层的代码实现在适当时会睡眠主线程。
真正会卡死主线程的操作是在回调方法onCreate/onStart/onResume等操作时间过长,会导致掉帧,甚至发生ANR,looper.loop本身不会导致应用卡死。
ActivityThread的main方法主要作用就是做消息循环,一旦退出消息循环,主线程运行完毕,那么你的应用也就退出了。
Android是事件驱动的,在Loop.loop()中不断接收事件、处理事件,而Activity的生命周期都依靠于主线程的Loop.loop()来调度,所以可想而知它的存活周期和Activity也是一致的。当没有事件需要处理时,主线程就会阻塞;当子线程往消息队列发送消息,并且往管道文件写数据时,主线程就被唤醒。
主线程在没有事件需要处理的时候就是处于阻塞的状态。想让主线程活动起来一般有两种方式:
第一种是系统唤醒主线程,并且将点击事件传递给主线程;
第二种是其他线程使用Handler向MessageQueue中存放了一条消息,导致loop被唤醒继续执行。
主线程Looper从消息队列读取消息,当读完所有消息时,主线程阻塞。子线程往消息队列发送消息,并且往管道文件写数据,主线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。因此loop的循环并不会对CPU性能有过多的消耗。
总结: Looer.loop()方法可能会引起主线程的阻塞,但只要它的消息循环没有被阻塞,能一直处理事件就不会产生ANR异常。
http://www.jianshu.com/p/cfe50b8b0a41
答:最开始Android的入口ActivityThread里面的main方法,里面有一个巨大的Handler,然后会创建一个主线程的looper对象,这也是为什么直接在主线程拿Handler就有Looper的原因,在其他线程是要自己Looper.prepare()的。
其实整个Android就是在一个Looper的loop循环的,整个Android的一切都是以Handler机制进行的,即只要有代码执行都是通过Handler来执行的,而所谓ANR便是Looper.loop没有得到及时处理,一旦没有消息,Linux的epoll机制则会通过管道写文件描述符的方式来对主线程进行唤醒与沉睡,Android里调用了linux层的代码实现在适当时会睡眠主线程。
真正会卡死主线程的操作是在回调方法onCreate/onStart/onResume等操作时间过长,会导致掉帧,甚至发生ANR,looper.loop本身不会导致应用卡死。
ActivityThread的main方法主要作用就是做消息循环,一旦退出消息循环,主线程运行完毕,那么你的应用也就退出了。
Android是事件驱动的,在Loop.loop()中不断接收事件、处理事件,而Activity的生命周期都依靠于主线程的Loop.loop()来调度,所以可想而知它的存活周期和Activity也是一致的。当没有事件需要处理时,主线程就会阻塞;当子线程往消息队列发送消息,并且往管道文件写数据时,主线程就被唤醒。
主线程在没有事件需要处理的时候就是处于阻塞的状态。想让主线程活动起来一般有两种方式:
第一种是系统唤醒主线程,并且将点击事件传递给主线程;
第二种是其他线程使用Handler向MessageQueue中存放了一条消息,导致loop被唤醒继续执行。
主线程Looper从消息队列读取消息,当读完所有消息时,主线程阻塞。子线程往消息队列发送消息,并且往管道文件写数据,主线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。因此loop的循环并不会对CPU性能有过多的消耗。
总结: Looer.loop()方法可能会引起主线程的阻塞,但只要它的消息循环没有被阻塞,能一直处理事件就不会产生ANR异常。
http://www.jianshu.com/p/cfe50b8b0a41
相关文章推荐
- 关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?引发的思考,事实可能不是一个 epoll 那么 简单。
- 主线程中的Looper.loop()一直无限循环为什么不会造成ANR?
- Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
- Android面试:主线程中的Looper.loop()一直无限循环为什么不会造成ANR?(转)
- Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
- 为什么Android程序中的Looper.loop()不会造成ANR异常
- Android为什么主线程不会因为Looper.loop()里的死循环卡死
- Android面试:主线程中的Looper.loop()一直无限循环为什么不会造成ANR?(转)
- 主线程中的Looper.loop()一直无限循环为什么不会造成ANR?
- Looper.loop死循环为什么不会卡死
- Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
- 关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
- Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
- Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
- Android中为什么主线程不会因为Looper.loop()里的死循环卡死
- 为什么在主线程的Looper.looper死循环不会卡死
- Android中为什么主线程不会因为Looper.loop()方法造成阻塞
- Android的Looper的无限循环为啥不会ANR?
- 为什么在主线程的Looper.looper死循环不会卡死
- Android中为什么主线程不会因为Looper.loop()方法造成阻塞