ANR:程序无响应;
activity的处理时间是5S;
Service的处理时间是20s;
BroadCastReceiver的处理时间是10s;
当我们的时间没有在这个时间内处理完成,就会造成ANR,但是ANR到底是什么东西,我们就要进一步去探究了!
InputManagerService
所有的触摸事件的处理都是通过IMS去管理的,这个一个远程的服务进程,它的初始化是在SystemService开始的时候,在开启IMS的同时也开启了WindowManagerServidce,并且WMS中会持有IMS的引用,IMS是用来接收触摸事件的,而WMS一般是用来处理事件的。
IMS 是通过一种叫epoll的机制来监听所有的手机设备的输入事件,
epoll
在linux系统下一切都是文件,所以我们手机的设备都可以看成为一种文件,但是这个epoll就是持有这些文件的文件描述符,由于它对这个文件的存储结构是一个红黑树存储结构,当一个文件的文件描述符发生了变化,它能以O(1)的时间复杂度查到到对应的文件并对其进行读写操作;
select
这是epoll的前身,它对比与epoll的时间主要是消耗在,它是在链表中存储了所有的文件的文件描述符,而且查询的时候是通过轮询来查找的,所以他的反应是比较慢的;
在IMS初始化的时候初始化了一个叫EventHub的对象,这个对象是封装了上面提到的epoll对象,这个对象主要的工作是在内部创建了两个对象:InouotReade和InputDispatcher,这两个对象的主要任务分别是:从eventhub 中读取事件,inoutdispatcher是将事件分发给WMS.
由于dispthcer的时候会找到对应的那个window,但是他们处理都是在SystemServer中处理的要将事件发送到app进程中,一般我们想到的是通过binder来实现,但是这里它却不是通过binder来实现的,而是通过socket 来传输的,如果仔细阅读过ViewRootImpl的源码,在ViewRootImpl的成员方法setView的时候他初始化了这个Socket;
在事件分发过程中会调用java层的IMS的notifyANR方法,获得AMS中的timeout,也就是5s,如果时间超过了这个时间,那么就会调用Ams中的这个notifyANR然后弹出系统的dialog。