博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为什么在子线程中不能更新UI的简单解释
阅读量:7052 次
发布时间:2019-06-28

本文共 1021 字,大约阅读时间需要 3 分钟。

hot3.png

 子线程中更新UI会报错的那个方法:

at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8358)
void checkThread() {     if(mThread!= Thread.currentThread()) {         throw newCalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views.");     }}

     当访问UI时,ViewRootImpl会调用checkThread方法去检查当前访问UI的线程是哪个,如果不是UI线程则会抛出异常,这是没问题的。但是为什么一开始在MainActivity的onCreate方法中创建一个子线程访问UI,程序还是正常能跑起来呢?

     ViewRootImpl的创建在onResume方法回调之后,而我们一开篇是在onCreate方法中创建了子线程并访问UI,在那个时刻,ViewRootImpl是没有创建的,无法检测当前线程是否是UI线程,所以程序没有崩溃一样能跑起来,而之后修改了程序,让线程休眠了200毫秒后,程序就崩了。很明显200毫秒后ViewRootImpl已经创建了,可以执行checkThread方法检查当前线程。

那为什么Google要规定不能在子线程中不能更新UI呢:

    首先UI线程(mainThread)并不是线程安全的,这样如果子线程修改UI容易数据错乱,如果做到线程安全的话,这样做是很低效的。其次谷歌推荐如果子线程需要修改UI可以使用handler,这样的队列设也是考虑到并发,效率的体现。为什么 android 会设计成只有创建 ViewRootImpl 的原始线程才能更改 UI 呢?这就要说到 Android 的单线程模型了,因为如果支持多线程修改 View 的话,由此产生的线程同步和线程安全问题将是非常繁琐的,所以 Android 直接就定死了,View 的操作必须在创建它的 UI 线程,从而简化了系统设计。有没有可以在其他非原始线程更新 UI 的情况呢?有,SurfaceView 就可以在其他线程更新UI。

 

 

转载于:https://my.oschina.net/u/2987490/blog/1456899

你可能感兴趣的文章
大型网站技术架构(一)大型网站架构演化
查看>>
Java基础学习总结(16)——Java制作证书的工具keytool用法总结
查看>>
ORACLE 绑定变量用法总结
查看>>
ssh证书登录
查看>>
Swoole学习笔记(五):多协议多端口
查看>>
211学院的小胖子钟情好程序员
查看>>
表格操作
查看>>
用python读写excel文件
查看>>
【Enterprise Manager 12c】如何在EM 12c中配置Exadata Infiniband告警邮件
查看>>
盆盆的11年Microsoft MVP心路历程
查看>>
利用kickstart实现pxe自动安装
查看>>
推荐一个spring的demo网站
查看>>
如何利用互联网工具调研网站
查看>>
最新 Hadoop 视频分享
查看>>
3_Shell语言———输入输出重定向和管道概述
查看>>
快速了解linux压缩与解压
查看>>
SQL :多条记录取最前面一条或根据条件任取N条。。。。。。
查看>>
再谈javascript 获取服务器控件值的
查看>>
Android官方数据绑定框架DataBinding(三)
查看>>
ioctl 函数
查看>>