面试别再问我子线程为什么不能更新UI了

又到了对于程序猿的跳槽的黄金季节(金三银四),面试是一个必须经历的环节,不得不开始一遍又一遍的刷题,遇到不会的开始google,度娘……

当一个问题掌握的不是刨根问底式的扎实,一不小心被较(恶)真(毒)面试官的刨根的话,会显得很尴(sha)尬(x),下面开始举例……

(头像)面屎官:你项目里哪里用到了rxjava……
(头像) __me : 网络请求的时候……
(头像)面屎官:具体用来干什么……
(头像) __me : 用来切换线程……
(头像)面屎官:为什么要切换线程……
(头像) __me : 因为子线程不能更新ui(脱了裤放屁,你问个有技术含量的好不好)
(头像)面屎官:为什么子线程不能更新ui
(头像) __me : 因为……………………(我去,会崩掉呀)

当然了,崩掉是必然的,但是为了满足面屎官的好奇心,必须一探究竟

一段测试代码


面试别再问我子线程为什么不能更新UI了_第1张图片
WechatIMG1689.jpeg

点击控件,logcat会报如下错误:


WechatIMG1688.jpeg

跟踪错误日志点进去


WechatIMG1690.jpeg

发现在setText()的时候,会检查线程是否属于Ui线程,否则就会抛出异常
有一种情况:在onCreate()或者onStrart()方法中开启子线程更新ui就不会抛出异常,追踪源码

发现检查线程的调用在onResume()之后初始化实例


面试别再问我子线程为什么不能更新UI了_第2张图片
WechatIMG1691.jpeg

到现在还是没有回答面试的问题,为什么不在子线程中更新ui,google为什么这么设计,原理其实不难理解,主要问题是java的线程安全,如果不在主线程更新ui,多个子线程同时给TextView设值,TextView的显示就会出现问题,不知道最终显示哪一个线程的值

rxjava也好,asyncTask也好,祖宗都是thread+handler,为什么通过handler切换线程就可以了呢,调用handler的sendMessage方法,发送message到主线程的messageQueue,loop循环取出,然后处理,全部的操作在同一个线程中排序执行,从而避免引发线程安全。
总结,子线程不能更新ui的原因就是为”线程安全“考虑。


面试别再问我子线程为什么不能更新UI了_第3张图片
webwxgetmsgimg.jpg

你可能感兴趣的:(面试别再问我子线程为什么不能更新UI了)