关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?引发的思考,事实可能不是一个 epoll 那么 简单。...
( 转载请务必标明出处:http://www.cnblogs.com/linguanh/, 本文出自:【林冠宏(指尖下的幽灵)的博客】)
前序
本文将会把一下三个问题阐述清楚以及一个网上的普遍观点的补充:
1,安卓 APP 启动过程,对于Activity 的 onCreate 等生命周期的函数为什么不会因为 Looper.loop()里的死循环卡死而永无机会执行。
2,在 1 的基础上,View 的绘制到底是怎样完成的,它又为什么不会因为 Looper.loop()里的死循环卡死而永无机会刷新。
3,网传的观点大概如下:
1.handler机制是使用pipe来实现的
2.主线程没有消息处理时阻塞在管道的读端
3.binder线程会往主线程消息队列里添加消息,然后往管道写端写一个字节,这样就能唤醒主线程从管道读端返回,也就是说queue.next()会调用返回
4.dispatchMessage()中调用onCreate, onResume
下面的阐述中,将采用:先告知答案,再放直观图片,最后文字辅助解析的顺序。
总结:View 的底层绘制是基于Binder进程通讯触发,由底层 SurfaceFlinger 的工作线程中的事件机制,包含 handler ,looper,messageQueue 来进行接收、处理,它和 ActivityThread 的 Handler 没关系,即是与 ActivityThread 几乎无关,但是如果在ActivityThread 里面调用 View的相关函数,例如 handleMessage 的一个 setText(..),最终触发到View其它底层函数,它将会将这些信息发送到 SurfaceFlinger 的事件机制中去,被对应处理,最终刷新到界面。
点我查看 PDF 图片
1 void checkThread() { 2 3 if (mThread != Thread.currentThread()) { 4 5 throw new CalledFromWrongThreadException( 6 7 "Only the original thread that created a view hierarchy can touch its views."); 8 9 } 10 11 }
代码第三行,其中 mThread 是创建 ViewRootImpl 的线程,而ViewRootImpl是在主线程中创建的,所以,我们习惯地称它为主线程,mThread和当前代码运行的线程来做了个等式运算,相同就出错,也就是说,并不是子线程不能刷新UI,准确来说,是发送进行 UI 刷新消息的消息,因为真正的底层刷新也不是当前 APP 的主线程。而是限制了,如果当ViewRootImpl是由子线程创造的,那么就可以在该子线程中发送更新UI的消息,自然地就能更新了,那么为什么限制呢?
下面解析引自知乎
因为不光是gui,同样的道理在几乎所有编程领域里都是这样的,这背后是线程同步的开销问题。显然两个线程不能同时draw,否则屏幕会花;不能同时insert map,否则内存会花;不能同时write buffer,否则文件会花。需要互斥,比如锁。结果就是同一时刻只有一个线程可以做ui。那么当两个线程互斥几率较大时,或者保证互斥的代码复杂时,选择其中一个长期持有其他发消息就是典型的解决方案。所以普遍的要求ui只能单线程。
关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?引发的思考,事实可能不是一个 epoll 那么 简单。...相关推荐
- (转)关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?引发的思考,事实可能不是一个 epoll 那么 简单。...
( 转载请务必标明出处:http://www.cnblogs.com/linguanh/, 本文出自:[林冠宏(指尖下的幽灵)的博客]) 前序 本文将会把一下三个问题阐述清楚以及一个网上的普遍观点的补 ...
- 【Android 异步操作】Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )
文章目录 一.判定当前线程是否是主线程 二.子线程中执行主线程方法 三.主线程中执行子线程方法 一.判定当前线程是否是主线程 在 Android 中 , 如果要判定当前线程是否是主线程 , 可以使用如 ...
- android handler 主线程吗,[android开发]非主线程进行handler操作
[android开发]非主线程进行handler操作 (2012-10-30 16:26:01) 标签: 杂谈 android默认对主线程创建有消息队列及looper(looper是对消息队列的操作类 ...
- 为什么Android必须在主线程更新UI?
为什么Android必须在主线程更新UI? 站在各位大牛的肩膀上,谢谢! 正常情况下,Android需要在UI线程更新UI,然鹅,在特殊情况下,子线程也能更新UI不在讨论之列,可参考Android中子 ...
- 为什么 Android 必须在主线程更新 UI ?
点击蓝字 关注我们 为什么Android必须在主线程更新UI? 站在各位大牛的肩膀上,谢谢! 正常情况下,Android需要在UI线程更新UI,然鹅,在特殊情况下,子线程也能更新UI不在讨论之列,这篇 ...
- java 主线程_Java中的主线程 - Break易站
Java 多线程 Java为多线程编程提供内置支持.多线程程序包含两个或多个可以并发运行的部分.这样的程序的每个部分称为线程,每个线程定义一个单独的执行路径. Java中的主线程 当Java程序启动时 ...
- 【Android面试】主线程中的Looper.loop()一直无限循环为什么不会造成ANR?
Android面试中,你也许会被问到题目中的问题,这里我们基于以下几点来延伸解读其中原因: 1.什么是ANR?ANR发生的原因是什么? 2.Looper为什么要无限循环? 3.线程的几种状态 4.主线 ...
- Android线程之主线程向子线程发送消息
和大家一起探讨Android线程已经有些日子了,谈的最多的就是如何把子线程中的数据发送给主线程进行处理,进行UI界面的更新,为什么要这样,请查阅之前的随笔.本篇我们就来讨论一下关于主线程向子线程如何发 ...
- 在子线程中更改主线程中的控件的信息,在子线程中用toast
一丶在子线程中不允许更改主线程中的控件的信息,也不允许在子线程中用toast,我们要更改的话 (1)消息机制:使用handler (由主线程调用) 在主程序中Handler handler = new ...
- android 4.0主线程访问网络问题
在4.0以下,在主线程中访问网络,如果请求超过6s的话,就会报ANR,那么这就会带来一个问题,如果网络慢或者请求的数据过大时,界面会卡顿,造成界面灵敏性很差,因此网络请求一般不能放在主线程中操作,go ...
最新文章
- 周三多管理学第七版pdf_考研(管理学)相对好考的211院校推荐
- 无责任Windows Azure SDK .NET开发入门篇三[使用Azure AD 管理用户信息]
- raspberry树莓派NFS搭建
- python多态_Python 简明教程 21,Python 继承与多态
- php单表显示动态下拉框,PHP:使用optgroup动态下拉列表
- maven 包的导入
- sql 解析 java_将Java 8流解析为SQL
- java 根据星期计算日期_Java 根据指定日期计算所在周的周一和周日
- 字符串+流+java_Java读取流并拼接转换成字符串
- javascript 函数的变量与作用域
- 视频切割(解决音视频不同步问题)
- 倒计时器 (WPF)
- 如何知道 win10 的激活到期时间和期限等
- 苹果个人账号转公司账号
- 水星mac1300r虚拟服务器,水星(MERCURY)MAC1300R路由器用手机怎么设置?
- Python自学笔记1(think python)
- VR全景打造数字化校园名片
- FileExplorer for iPhone
- 金融危机的影响(ISAS课题)
- MySQL 监控软件lepus天兔
热门文章
- vc++之剪贴板通信实例
- 异常检测算法:孤立森林(Isolation Forest)
- Tensorflow:tfrecord数据读取和保存
- java做图形界面计算n_n皇后问题回溯法---java图形界面实现回溯过程
- 蓝桥杯2018年第九届C/C++省赛B组第七题-螺旋折线
- Kotlin — 竞技程序设计(类似天梯训练)
- Flutter高级第7篇:点击穿透问题、页面禁止左右滑动
- Futter基础第13篇: 实现Drawer侧边栏、以及侧边栏内容布局
- Android 饼状图(MPAndroidChart框架)
- 数据库保存经纬度,需要采用什么数据类型,小数点应该精确多少位?