Android子线程可以setText吗

373 阅读1分钟

首先我们看下TextView的源码,如下图所示: image.pngTextView的源码中可以找到在执行setText()方法时一定会执行requestLayout()invalidate()方法,而在requestLayout()中代码如下图所示: image.png ViewRootImpl viewRoot = getViewRootImpl();获取的ViewRootImpl类是ViewParent接口的实现类 image.pngViewParent接口中有requestLayout()方法需要实现,如下图所示: image.png 这时后再看图二中红框标注的mParent.requestLayout()就会发现mParent其实就是一个viewParent接口具体实现类的对象也就是ViewRootImplimage.png 再看ViewRootImplrequestLayout()的具体实现如下图所示: image.png 想必到了这里大家看到checkThread()就已经猜到了子线程不能更新ui的异常是怎么抛出的,还是看下具体的代码: image.png 到了这里大家就会有疑问了,那为什么子线程setText()没有异常呢,那是因为如果你图一中的 invalidate()方法是线程第一行代码执行而requestLayout()检查线程是个耗时操作,invalidate()方法快于requestLayout()检查到线程异常就不会报错。出自古龙小李飞刀的天下武功,唯快不破!放在代码中同样适用,想要验证这个结论你可以在setText()之前Thread.sleep(1000) 让线程休眠1s试一下,你就会发现本来正常的代码突然抛出异常了!