阅读本文大概需要4分钟。

和小张聊到兴起,我就问了android面试界一个众所周知的问题。

我:之前说到每个线程的looper都在不断的从message queue里取message来处理,那android系统是如何做到“不断”二字的?

小张快速回到答:这个我看过一些技术文章里剖析过源码,我记得是Looper是在loop()方法里通过for(;;)死循环里的Message msg = queue.next()这句话来不断获取message queue里的下一条message。

我继续问道:没错,看来你的确接触过这块儿的源码,而且记忆力还挺不错啊。

紧接着我又问道:我们都知道在UI线程里,系统预先为我们创建了一个looper,那么UI线程里的looper这个死循环岂不是占用了所有CPU资源,一打开app岂不是卡出翔?但是我们平时用app很流畅啊,这是怎么回事啊?

听到这个问题,看小张脸色犯难,感觉当时小张的心情是这样的:

小张:哦,是这样的 ...怕什么来什么,躲是躲不过去了,只好硬着头皮扛下去。

小张沉思片刻,说道:我记得这个循环比较特殊,并不是普通的死循环,queue.next()是一个可能阻塞线程的操作,也就是说可能会交出CPU执行时间片,而不至于导致卡顿或者ANR发生。

我听后,感觉有得聊,于是打算趁机打算再深入一步。

继续问道:queue.next()看起来像是去queue里获取下一条可以处理的message,你能否对这块儿的逻辑说得详细一些呢?

小张:嗯,可以。如果message queue检查到单链表里没有任何message存在,就会使得线程阻塞在此处,因为没有任何message可以返回使得loop()方法继续下面的处理逻辑,因此也没有可执行的代码片段,对于CPU来讲此线程将会进入休眠,就会把时间片分配给其他线程。

如果message queue检查到单链表队首有message可以立即返回[注1],交给loop()执行接下来处理此message 的逻辑,处理完逻辑后。for(;;)又会紧接着循环到开头的queue.next()问其要下一条message,如此周而复始...

听完小张的回答,我是比较满意的,毕竟到目前为止,我面的候选人里能回答到这一步的都比较少,心里对小张的印象分提高了不少。

为了考察小张对这个问题的理解到底有多深,我决定打破砂锅问到底。

我:嗯,很好很好。你的理解基本上是正确的,但这里面有个问题不知道你考虑过没有,就是当message queue在检查到没有message时进入了休眠。

那如果此时,用户此时来一个按钮点击事件,点击事件包装成的message被handler扔进来时,message queue又如何知道,从而立即做出反应?

毕竟UI线程是不能错失任何一个message的,否则对用户来说就是点击没有反应,对吧?

估计小张听完感觉内心快崩溃了...

小张:这个我只记得queue.next()的源码里有个nativePollOnce()进入了JNI C代码里,有立即执行的message就会立即返回,没有的话nativePollOnce()无法返回,线程就会进入休眠。如果此时有message来时,这里面的逻辑就会唤醒线程,重新进行获取message的逻辑...

我看小张的回答稍显模糊,估计是到了他理解的极限了,但毕竟离真相只差最后一步了,我怀着试一试的态度,打算做最后的试探。

于是问道:嗯嗯,能够理解到这个程度相当不错了。那能够最后说一下你刚才提到的”唤醒“这块具体是怎么实现的吗?

小张故作思考了一下道:这块儿...不是很了解...

我试图引导道:看nativePollOnce()这个函数的名字,有没有感觉很像Linux的什么机制?

小张经过提示,貌似想起了什么,小声问道:你说的是Linux的epoll吗?

到了这一步,我直接摊牌:是的,正是大名鼎鼎的epoll,epoll机制提供了Linux平台上最高效的I/O复用机制,它能够在一个地方等待多个文件句柄的I/O事件。

简而言之,就是android使用pipe管道创建两个fd文件描述符,nativePollOnce方法中正是承载着这个管道的读操作,根据fd知道是管道读端有可读事件。

当有message来临时,比如触摸事件,即会调用message.enqueueMessage(),添加完message后,调用了native层的nativeWake方法,就会向管道写端写一个“W”字符[注2],这样就能触发管道读端从epoll_wait函数返回,从而达到唤醒线程的目的,从nativePollOnce()处继续执行下去。

看小张似懂非懂的的表情,我知道这个可能一时半会儿解释不清楚了。

就微笑着说道:没事儿,你回答得已经挺好的了,关于pipe/epoll这块儿的知识点,你可以后面回去查资料了解一下。

小张点了点头,道:嗯,的确是,对于操作系统的底层知识,的确是我的薄弱点,我一定会加强。

[注1]:这里并非有message即返回,因为此message有可能是由postDelay发送的延时处理消息,不可立即执行,需要等到时间到时才执行。关于此种情况,请见下一篇。

[注2]:关于这里是如何触发的,请等后面的文章。


欢迎转发,关注公众号

android ontoch事件无反应_一切从android的handler说起(三)相关推荐

  1. android touch事件无反应,触摸屏 无响应

    (609条消息) android touch事件无反应,android的touch事件分发响应机制_蒙娜lisa的博客-CSDN博客 (609条消息) android touch事件无反应,移动端to ...

  2. android hook 模拟点击_手把手讲解 Android Hook-实现无清单启动Activity

    手把手讲解系列文章,是我写给各位看官,也是写给我自己的. 文章可能过分详细,但是这是为了帮助到尽量多的人,毕竟工作5,6年,不能老吸血,也到了回馈开源的时候. 这个系列的文章: 1.用通俗易懂的讲解方 ...

  3. android touch事件无反应,android的touch事件分发响应机制

    想要弄明白android的touch事件分发响应机制需要先充分理解一下几个知识点: View和ViewGroup touch事件的构成 ViewGroup如何对事件分发和拦截 View和ViewGro ...

  4. android找不到符号_快速搭建Android开发环境——Android Studio(附ADB找不到设备)...

    由于毕设大概率最终要使用Android来实现,所以现在要开始学习一些Android开发基础了. 学习一门技术,最先要解决的问题就是开发环境的问题. 就如同两年前学java那样,在windows下配置环 ...

  5. android线上内存监控_如何在Android上监控(和减少)您的数据使用情况

    android线上内存监控 Increasingly sophisticated phones and data-hungry applications make it easier than eve ...

  6. android touch事件无反应,移动端touch事件

    当用户手指放在移动设备在屏幕上滑动会触发的touch事件 webkit: touchstart--当手指触碰屏幕时候发生.不管当前有多少只手指 touchmove--当手指在屏幕上滑动时连续触发.通常 ...

  7. android 长按缩放拖动_十年Android之路面试2000人,面试准备+内部泄露核心题(中高级)...

    前言 先介绍一下自己:曾服务于东芝,东方集团,阿里,三一重工,有15年项目开发经验,熟悉汇编,java,c/c++开发语言,对系统底层,web开发和移动端开发有较深入研究.主要涉及应用层mis,erp ...

  8. android 触摸事件 取消,如何禁用/重新启用Android中的触摸事件?

    快速,可能很简单,问题.我有一个视图,其背景是动画,在那段时间,我想禁止用户与视图交互.我的视图是一个FrameLayout,我用onTouchEvent()捕获触摸事件.我试过的解决方案:如何禁用/ ...

  9. android 代码设置 键盘适应_详细讲解Android修改键盘文字的方法

    1.首先,针对EditText的设置 在xml布局中,针对EditText的设置. android:layout_width="match_parent" android:layo ...

最新文章

  1. android xml 文件里面的宽度Match_Parent 被 替换成了wrap_content
  2. 【Linux】——常见的rc的含义
  3. 浅谈Python中的编码规则
  4. PendingIntent传值接收时为null
  5. java多线程内存模型_Java多线程内存模型
  6. Java Swing Mysql学生信息管理系统
  7. tree工具类 TreeUtils.java
  8. 【深度学习】你该会的精选面试题(二)
  9. Purftpd的详细安装配置
  10. 春节后面试别人的经历总结之一,好岗位分享给还在找工作中的软件开发爱好者们
  11. 重磅精品课程总有一门是你想要找的
  12. 经营性网站必须要办理ICP增值电信业务经营许可证吗?
  13. PMOS与NMOS场效应管相关知识点
  14. 第一次.......
  15. 【OpenGL】画线算法
  16. 几本OpenCV的参考书籍
  17. 【转】强悍的搞笑语录,老衲再也忍…
  18. matlab柱状图之间连续,matlab 离散曲线图、连续曲线图、柱状图
  19. 2005新年健康生活大排雷
  20. 我真没想写图书管理系统啊

热门文章

  1. 实验六 数组 (2)
  2. 安装mysql5.5时常见错误--缺失make
  3. GO语言基础之method
  4. MySQL TEXT数据类型的最大长度
  5. Image.Save()发生“GDI+ 中发生一般性错误”
  6. mybatis如何根据mapper接口生成其实现类
  7. Spring组件扫描context:component-scan/使用详解
  8. Oracle与OpenJDK之间的区别
  9. PHP生成日历(实例详解)
  10. WeChat微信小程序image组件aspectFill:保留中部 等比例变化 Widthfix:宽度为指定的  高度依据原图的宽高比进行变化