为什么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

更多相关文章

  1. Android(安卓)App卡顿慢优化之多线程优化
  2. ios开发之ios中控件
  3. Android技术博文汇总
  4. 从华为事件,看 Google Android(安卓)的独断专制!
  5. react-navigation使用及dva初探二
  6. Android(安卓)Handler 机制
  7. Android的Handler,Looper源码剖析
  8. 转:Android(安卓)之 下拉框(Spinner)的使用
  9. [置顶] 【Android归纳决】Asynctask与Handler异步综述

随机推荐

  1. [Android 特效] Android 通过流播放声音(
  2. Android写Logcat文件保存到SD卡
  3. android用Popup弹出窗(PopupWindow的使用
  4. 教你怎么配置Android的AndroidManifest.x
  5. android4.2上获取应用程序大小的变更点
  6. Android Widget程序源码
  7. Gradle sync failed: Gradle DSL method
  8. 用于做 Android 屏幕自适应的文章资源
  9. Android程序设置成横屏方法
  10. Android 从uri中获取路径