Android UI线程更新并不是线程安全的,并且必须在UI线程中进程UI更新操作,以下面一个错误为例:
public class MainActivity extends Activity {
private String title;
private Button btn;
private final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
setTitle(title);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.time);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Timer timer = new Timer();
timer.schedule(new MyTask(), 1000);
}
});
}
class MyTask extends TimerTask{
Message msg;
Bundle bundle;
SimpleDateFormat sdf;
public MyTask(){
Message msg = new Message();
Bundle bundle = new Bundle();
sdf = new SimpleDateFormat();
}
@Override
public void run() {
String date = sdf.format(new Date());
//在子线程中更新UI
setTitle("当前时间 :"+date);
}
}
}
上面的例子会报
“Only the original thread that created a view hierarchy can touch its views.”
正确的写法应该是在子线程中组装数据,然后通过handler发送消息给UI线程,最后在UI线程中更新UI:
public class MainActivity extends Activity {
private Button btn;
private final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//接收消息
switch (msg.what) {
case 110:
Bundle bundle = msg.getData();
String date = bundle.getString("date");
//更新UI
setTitle(date);
break;
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.time);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Timer timer = new Timer();
//设置每秒执行一次
timer.schedule(new MyTask(),0,1000);
}
});
}
class MyTask extends TimerTask{
Message msg;
Bundle bundle;
SimpleDateFormat sdf;
public MyTask(){
msg = new Message();
bundle = new Bundle();
sdf = new SimpleDateFormat("yyyy年MM月dd : HH时mm分ss");
}
@Override
public void run() {
//组装数据
String date = sdf.format(new Date());
msg.what = 110;
bundle.putString("date", date);
msg.setData(bundle);
//发送消息
handler.sendMessage(msg);
}
}
}