子线程真的不可以更新UI吗?
以前我也认为不可以的,但是做了一个测试。
onCreate中
new Thread(new Runnable() { @Override public void run() { tv.setText("290471290847120"); } }).start();竟然奇迹般的可以了!我才意识到 以前都是道听途说 什么东西 都得自己去验证一下
但是
new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } tv.setText("290471290847120"); } }).start();子线程休眠3秒以后,就报错了!
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
意思就是只有UI线程才能更新UI。
只能追溯源码了
setText追溯下去 一直可以追溯到invalidate,最后会追溯到
void checkThread() { if (mThread != Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views."); } }这个方法。检查了线程是不是主线程。
但是为什么在onCreate中为什么没有进行检查呢?checkThread是位于view root impl类中的。这个类在未来某个时候才被初始化,所以你在view root impl类实例化之前,修改视图,比如setText,是不会视图重绘的。
一句话总结,如果在view root impl类初始化前,会进行进程的检查;反之,会进行检查。