概述
学Android有一段时间了,一直觉得线程很难,原因大概是不常用吧! 正所谓陌生生难,就像刚刚接触编程都觉得编程不简单一样,多用用就熟悉了。
而线程正是Android初级者进阶的一个标志,必须要正面刚!
问题一:其他线程更新UI。
private void showTime() {
new Thread(){
@Override
public void run() {
//月份是从0-11算的,所以显示的话要+1
String times = time.year + "年" + time.month+1 + "月" + time.monthDay
+ "日" + time.hour + "时" + time.minute + "分" + time.second + "秒"
+ ":现在是一年中的第" + time.yearDay + "天";
tvTime.setText(times);
}
}.start();
报错:Only the original thread that created a view hierarchy can touch its views.
然后百度:
参考文献:http://www.xuebuyuan.com/2120593.html
这个错误很常见,基本上写线程操作都遇到过这个错误。根本原因是view控件的线程安全问题,通俗点讲就是所有的更新UI操作都需要在主线程(也就是UI线程中完成),而不能在新开的子线程中操作。总之一句话——不能在其他线程里更新UI!
解决方案:
- 在主线程中new一个Handler类(注意导入android.os.Handler;包),并重写handleMessage()方法。
- 新开启一个线程,将run里面跑的数据交给Message对象,然后将Message对象交给第一步new的handler.sendMessage().
- 在handlerMessage()方法里给组件赋值,更新UI。
看源码:
Handler handler=new Handler() {//第一步
@Override
public void handleMessage(Message msg) {
switch (msg.what){ //第三步
case 0x11:
tvTime.setText(msg.obj.toString());
break;
}
}
};
private void showTime() { //第二步
new Thread(){
@Override
public void run() {
while (!quit){
// 等待一秒钟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//月份是从0-11算的,所以显示的话要+1
time.setToNow();
times = time.year + "年" + time.month+1 + "月" + time.monthDay
+ "日" + time.hour + "时" + time.minute + "分" + time.second + "秒"
+ ":现在是一年中的第" + time.yearDay + "天";
Message msg=Message.obtain();
msg.what=0x11;
msg.obj=times;
handler.sendMessage(msg);
}
}
}.start();
}
我这里是用线程不断显示当前时间,精确到秒。这是主要步骤
待续——
总结:
大前提:线程分为主线程和其他子线程,每个线程里还都有一个Handler,handler还有looper。规则:只能在主线程(UI线程)中更新UI,子线程只能处理数据。
就像一个国家,把资源领土什么的分给各个地方,但是地方必须把产出上交中央,然而并不是直接上交而是通过某个机构,地方也可以有下级,下级上交也是如此。各个不同地方交换数据也是如此,但不能显示数据。