为什么在Android 5(棒棒糖)上可以直接从其他线程更改UI视图



请考虑以下代码:

new Thread() {
    @Override
    public void run() {
        myTextView.setText("Some text");
    }
}.start();

在棒棒糖之前的安卓设备上,该代码会导致CalledFromWrongThreadException异常,但为什么它在棒棒糖安卓上工作正常?

测试环境:运行Android 5.1的Genymotion模拟器

代码位于 Fragment 类的 onCreateView() 方法内。

这是一个时间问题,例如在onCreate()中插入代码不会使三星Galaxy S3上的应用程序崩溃,也不会使Android 5.1上的Nexus 7 2013上的应用程序崩溃。但是,如果修改代码以使其不断更新文本视图:

    new Thread() {
        @Override
        public void run() {
            int count = 0;
            while (true) {
                SystemClock.sleep(16);
                ((TextView) findViewById(R.id.test)).setText(count++ + "");
            }
        }
    }.start();

然后它会在第 ~18 次调用时崩溃,当TextView.setText(String)无意中调用View.requestLayout();时,最终调用实际检查正确线程的ViewRootImpl.requestLayout()。这样做可能是为了将线程检查的开销降至最低。

到目前为止

我注意到的是,如果您在活动中创建新线程,代码将在没有错误的情况下编译和运行。

公共类 MainActivity 扩展 ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    new Thread() {
        @Override
        public void run() {
            txtName.setText("Some text");
        }
    }.start();
}

但是,如果在服务或异步任务中创建新线程,则会导致 CalledFromWrongThreadException 异常。

最新更新