一.Looper的死循环为什么不会导致ANR问题?
ANR问题是什么?
Service,Broadcast,provider,input的超时,与message没有半毛钱关系,所以不会导致ANR。
二.什么是epoll机制?
epoll机制来源
最早的时候,linux的(请求)通知机制是请求方不停地去轮询发送请求,也就是每隔几秒就会发送请求,这种方式太损耗发送方的性能和资源了。
于是就改为第二种方式,也就是当请求方发送请求之后,就会阻塞:一直等待接收方,直到接收方把相应数据消息返回回来,发送方才关闭请求。但这样的话,有不好的地方,如果接收方一直没回应,发送方就一直阻塞在这里,还有,假如有100个请求发送给接收方,只有50条请求是有数据返回过去,剩下50条不用返回数据,这时服务器就会不断循环这100条然后进行判断哪条需要发送数据,哪条不用发送数据,这样也很消耗服务器资源和性能,因为的app这么多人使用,同一个时间内能发送几百万条请求也不是不可能的。
因此基于上面种种,就有了epoll机制,监听每个请求,并且用表记录每个请求的发送情况,当有数据发过来,就记录该请求是有事件发生的,然后epoll_wait就加1,表示这条请求连接它是有事件发生的,是需要返回数据的,那这样服务器就之后就不用遍历每条请求连接,因为只需去看这个表的记录情况,当检查到某条连接记录epoll_wait是发生变化的,则就表示需要返回数据,而没变化,则不用返回数据,继续让该请求连接保持休眠状态,然后下次再监听到该请求的表中的epoll_wait有变化,则就唤醒该连接,然后把数据返回给发送方,这样请求方也不用一直阻塞了。
epoll核心函数
epoll是Linux内核中的一种可扩展IO事件处理机制。大量应用程序请求时能够获得较好的性能。
int epoll create(int size)
创建一个epoll的句柄,size用来告诉内核需要监听的数目一共有多大
int epoll ctl(int epfd, int op, int fd, structepoll event *event)
epoll的事件注册函数
int epoll wait(int epfd, struct epoll event *eventsint maxevents, int timeout)
参数events用来从内核得到事件的集合maxevents 告之内核这个events有多大,这个maxevents 的值不能大于创建 epoll create() 时的size,参数 timeout 是超时时间 (毫秒,0会立即返回,-1将不确定,也有说法说是永久阻塞。
Handler里面运用
private native static long nativeInit();
MessageQueue(boolean quitAllowed) {
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
这里的nativeInit方法里面就是初始化epoll,然后把事件给初始化。
在MessageQueue的next方法中,当消息处理完了后会调用nativePollOnce(ptr, nextPollTimeoutMillis);
private native void nativePollOnce(long ptr, int timeoutMillis);
这里的nextPollTimeoutMillis就是休眠时间,也就是int epoll wait方法的timeout。
在MessageQueue的enqueueMessage方法里面会调用nativeWake(mPtr);
private native static void nativeWake(long ptr);
这样做就是唤醒,接着处理任务。