我对Android系统的工作方式感到困惑,尤其是在更新视图层次结构时。我们都知道,除了UI(Main)线程之外,我们不应从任何其他线程更新任何视图。当我们尝试这样做时,甚至Android系统也会引发异常。前几天,我试图在应用程序中实现显示视图的自定义进度。因此,我开始使用标准Java线程和处理程序组合。
当我能够从后台线程更新TextView时,我的发现使我感到惊讶。
new Thread(new Runnable() { @Override public void run() { mTextView.setText("I am " + Thread.currentThread().getName()); } }).start();
之后,我也尝试更新其他视图,效果很好。所以我尝试在后台线程中放置一个睡眠调用。
new Thread(new Runnable() { @Override public void run() { mTextView.setText("Thread : before sleep"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } mTextView.setText("Thread : after sleep"); } }).start();
并按预期崩溃
android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图。
然后,我尝试将setText()调用在sleep()调用之前和之后循环100次,1000次。当然,该应用程序每次都会崩溃,但我能够在textview上看到“睡眠前”文本。
所以我的问题是系统何时检测到某些非UI线程正在尝试更新视图。当非UI线程中没有sleep()调用时,为什么它不起作用?