這個誤區是:子線程不能更新 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();
}複製代碼