Only the original thread that created a view hierarchy can touch its views.
原来android中相关的view等控件不是线程安全的,我们必须单独做处理。这里借此引出Handler的使用。首先我们需要明白,主线程或者这里说的原始线程 original thread 一般情况下是UI线程,当然UI线程并不一定是主线程,我们不能长时间的阻塞该应用。但是在更新view以及相关控件的时候,必须使用主线程。
既然这样,我们就在子线程中通知主线程,让主线程做更新操作吧。那么,我们如何通知主线程呢?我们需要使用到Handler对象。
如果new一个无参构造函数的Handler对象,那么这个Handler将自动与当前运行线程相关联,也就是说这个Handler将与当前运行的线程使用同一个消息队列,并且可以处理该队列中的消息。
使用Handler的post方法可将线程添加到主线程的消息队列。
解决后的代码:
public class MainActivity extends Activity {
private Button button1 = null;
private TextView textView1 = null;
private String content = null;
private Handler handler = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建属于主线程的handler
handler = new Handler();
textView1 = (TextView) findViewById(R.id.textView1);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 本地机器部署为服务器,从本地下载a.txt文件内容在textView上显示
textView1.setText("正在加载......");
new Thread() {
public void run() {
content = "更新后的内容";
handler.post(runnableUi);
}
}.start();
}
});
}
// 构建Runnable对象,在runnable中更新界面
private Runnable runnableUi = new Runnable() {
@Override
public void run() {
textView1.setText(content);
}
};
}