为什么子线程中不能更新ui
Android实现View更新有两组方法,分别是invalidate和postInvalidate。前者在UI线程中使用,后者在非UI线程即子线程中使用。换句话说,在子线程调用 invalidate 方法会导致线程不安全。熟悉View工作原理的人都知道,invalidate 方法会通知 view 立即重绘,刷新界面。作一个假设,现在我用 invalidate 在子线程中刷新界面,同时UI线程也在用 invalidate 刷新界面,这样会不会导致界面的刷新不能同步?这就是invalidate不能在子线程中使用的原因。
public class MainActivity extends AppCompatActivity { private TextView main_tv;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
main_tv = (TextView) findViewById(R.id.main_tv); new Thread(new Runnable() {
@Override public void run() {
main_tv.setText("子线程中访问");
}
}).start();
}
}
程序正常运行不报错
public class MainActivity extends AppCompatActivity {
private TextView main_tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
main_tv = (TextView) findViewById(R.id.main_tv);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
main_tv.setText("子线程中访问");
}
}).start();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_test1:
new Thread(new Runnable() {
@Override
public void run() {
mTvTest.setText("子线程真的可以更新UI吗?");
}
}).start();
break;
}
}
以上两种都报错
正确更新的方式有
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 100) {
mTvTest.setText("由Handler发送消息");
}
}
};
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_test2: //通过发送消息
new Thread(new Runnable() {
@Override
public void run() {
mHandler.sendEmptyMessage(100);
}
}).start();
break;
case R.id.btn_test3: //通过Handler.post方法
new Thread(new Runnable() {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
mTvTest.setText("handler.post");
}
});
}
}).start();
break;
case R.id.btn_test4: //通过 view.post方法
new Thread(new Runnable() {
@Override
public void run() {
mTvTest.post(new Runnable() {
@Override
public void run() {
mTvTest.setText("view.post");
}
});
}
}).start();
break;
case R.id.btn_test5: //通过 activity 的 runOnUiThread方法
new Thread(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mTvTest.setText("runOnUIThread");
}
});
}
}).start();
break;
default:
break;
}
}
网友评论