这个误区是:子线程不能更新 UI ,其应该分类讨论,而不是绝对的。java
半小时前,个人 XRecyclerView 群里面,一位群友私聊我,问题是:面试
为何个人子线程更新了 UI 没报错?异步
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
title = (TextView) findViewById(R.id.title_tips);
doGet("http;//www.baidu.com", new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
title.setText(response.body().string()); // 这里在子线程更新了 text
}
});
}
private void doGet(String url,Callback callback) {
OkHttpClient client = new OkHttpClient();
Request.Builder builder = new Request.Builder();
Request request = builder.url(url).get().build();
client.newCall(request).enqueue(callback);
}复制代码
简单解析下。他用了 OkHttp 的异步 enqueue 的请求,并在成功后更新了 textView 的 text。ide
那么这样来讲,按照咱们被一直灌输的原理: 子线程不能刷新UI,上面这段代码妥妥地爆错啊。源码分析
上面的代码不必定爆错,它还会稳稳的顺利执行。ui
你能够尝试下。嫌麻烦,你能够运行下下面这段通透
的子线程更新UI代码url
public class TestActivity extends Activity {
private TextView title;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
title = (TextView) findViewById(R.id.title_tips);
new Thread(
new Runnable() {
@Override
public void run() {
// 子线程更新UI
title.setText("我 tm 妥妥地执行完毕");
}
}
).start();
}
}复制代码
试了的都知道,真 tm 执行了没爆错。spa
在看到他发给个人代码,onCreate
里面的部分,一切已经明了,这也是我以前面试几年经验的人设过的坑。下面我直接讲缘由,源码分析那些大家本身去看吧,你应该去看
。线程
void checkThread() {
// 该方法是 viewRootImpl.java 内部代码
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}复制代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
title = (TextView) findViewById(R.id.title_tips);
new Thread(
new Runnable() {
@Override
public void run() {
try {
// 等待 onResume 执行完,让 viewRootImpl 初始化完成
Thread.sleep(3000); // ---------- 这里,看这里
} catch (InterruptedException e) {
e.printStackTrace();
}
title.setText("我执行不了");
}
}
).start();
}复制代码