阅读此文需要对handler原理有一定的了解程度。

Handler 原理和源码

首先贴出来两个知识点。

第一 java线程可以休眠

第二Android只有主线程可以更新UI

有人觉得这是傻子都知道的知识,那接下来说傻子可能不知道的知识

直接叙述

所有java的入口都是main方法 由虚拟机调用,Android 的也不例外,刚开始学习那会根本没研究Android 从哪里开始执行的,现在我知道了告诉那些不知道的同学,不是从application。直接看源码ActivityThread

 

看到了吗?看到了吧。

再来一个惊天的大幂幂

 

当main 方法执行完毕之后,程序就会退出了。

那不对啊和我们看到的不一样啊,App启动之后可以一直运行啊,怎么解释。

直接解释,App一直运行这个是没错的,也就是说明main方法并没有执行完,看代码

 

先看3,如果main方法执行完到最后会抛一个异常,很明显我们的App并没有抛异常,那就说明Main方法没有执行完。

那怎么才能保证不会执行完毕呢?

这个问题就需要思考了,如果让我做,最先想到的就是开一个死循环,但是时间一长肯定就OOM了,

其实Android 也是这么做的  ,1处的代码 里面不给大家看了 大概的逻辑内容我文字带过

创建一个唯一的Looper 对象,然后绑定一个messageQueue队列 。(不懂的可以去看handler 详解)

然后看2 代码里边就是开启了Looper循环,一个死循环无限的从消息队列中去取消息(handler源码)。

这样的话我们的Main方法就卡在这里了,就不会执行完,程序也就是我们看到那样,一直在运行。

刚才我说了要是咱们写个死循环那估计领导就得找我们谈谈理想了,时间一长就OOM了,那为什么Android 可以这么搞呢,简单解释一下我也不懂也不深究,linux层去实现的,阻塞式循环,也就是有消息了就去执行消息,没有消息之后主线程就会休眠,前边说过了 java线程是允许休眠的(有兴趣的朋友可以去单独深究一下)

到这里了 如果你明白了这一点,就说明我的叙述能力还是可以的(如果没懂那就多看两遍,看到懂为止  哈哈)

主线程在main方法中开了一个阻塞式死循环,保证我们的程序不会退出。

问题2来了 

说是死循环,但是我们的App可不是死的,使能够接受交互的。

这里还是handler机制的功劳(不懂的可以去看handler 机制),当我们一个事件比如说一个点击、长按、滑动,都会通过handler 把这个事件封装成一个message 消息,并且放到Looper的死循环队列当中,这个时候的主线程就会被唤醒,然后对Message进行分发 ,这个时候事件已经被分配到了主线程当中,然后具体去执行,比如toast等等。这就是一个完整的事件处理流程。

那么问题来了 我们正常点击的速度是肯定没有程序执行快的,所以说不会有任何问题,但是如果一个点击事件当中执行了耗时操作,看下面代码

 

  这个点击了 会ANR吗?答案是不一定,

第一种情况,如果只点击了一次,主线程休眠十秒,没有问题,十秒之后主线程执行完毕,继续阻塞式休眠。

第二种情况,如果连续点击了多次,多个事件放到Looper 对象的MessageQueue当中 ,第一个事件去执行,主线程休眠十秒,然后第二个事件分发过来的时候,主线程还在sleep,这个时候我们的第二个事件就一直得不到执行,超过阀值就会ANR。

ANR 的原因 因为Looper对象MessageQueue队列中的事件没有能够得到及时执行。

阀值

按键事件 5s ,broadcast 10s、service ANR超时的定义在ActiveServices.java中,前台service无响应的超时时间为20秒,后台service为200秒

回到主题,Android 主线程looper 一直循环不会ANR

两个方面回答  第一,死循环不是造成ANR的必然原因 ,ANR是因为消息队列当中的事件没有得到及时的处理造成的。(但是我们写个死循环 基本上就会造成ANR,原因就是主线程一直在这里循环 ,后面的事件没有的到及时处理。 )

第二 主线程的Looper 循环 不会ANR最多就是OOM,为什么不会OOM上边解释了

更多相关文章

  1. 十分钟让你了解Android触摸事件原理(InputManagerService)
  2. Android零基础入门第34节:Android中基于监听的事件处理
  3. Android 事件全局监听(二)需要root权限 ,使用getevent监听Android输
  4. android详细解释键盘和鼠标事件
  5. Android Touch事件传递机制解析
  6. Android EventBus使用,粘性事件postSticky使用
  7. Android点击监听事件
  8. Android DownloadManager下载完成事件监听(系列4)

随机推荐

  1. Android中文文档v0.1 beta低调发布,期待
  2. Android(安卓)性能优化之布局优化 (二)
  3. Android中EditText属性
  4. android studio系列之使用指南
  5. Android(安卓)的消息队列模型
  6. android ViewPager不可滑动(android 项目
  7. Android学习之Android本地存储的五种方式
  8. Android手势监听类GestureDetector
  9. 在Android(安卓)Studio更改现有项目里的S
  10. Android(安卓)2.2 开发环境配置详解