Android子线程为什么可以setText的真正原因

首先我们看下TextView的源码,如下图所示:

image.png

TextView的源码中可以找到在执行setText()方法时一定会执行requestLayout()invalidate()方法,而在requestLayout()中代码如下图所示:
image.png

ViewRootImpl viewRoot = getViewRootImpl();获取的ViewRootImpl类是ViewParent接口的实现类
image.png

ViewParent接口中有requestLayout()方法需要实现,如下图所示:
image.png

这时后再看图二中红框标注的mParent.requestLayout()就会发现mParent其实就是一个viewParent接口具体实现类的对象也就是ViewRootImpl
image.png

再看ViewRootImplrequestLayout()的具体实现如下图所示:
image.png

想必到了这里大家看到checkThread()就已经猜到了子线程不能更新ui的异常是怎么抛出的,还是看下具体的代码:
image.png

到了这里大家就会有疑问了,那为什么子线程setText()没有异常呢,那是因为如果你图一中的 invalidate()方法是线程第一行代码执行而requestLayout()检查线程是个耗时操作,invalidate()方法快于requestLayout()检查到线程异常就不会报错。出自古龙小李飞刀的天下武功,唯快不破!放在代码中同样适用,想要验证这个结论你可以在setText()之前Thread.sleep(1000) 让线程休眠1s试一下,你就会发现本来正常的代码突然抛出异常了!

你可能感兴趣的:(Android子线程为什么可以setText的真正原因)