先说一下这个问题发现的原因:
2015年1月22日晚上的时候,正在看《疯狂Android讲义》。
看到其中的FrameLayout的例子的时候,觉得挺有意思就做了一个试试,就是一个能变换颜色的霓虹灯的样子。是这个样子的:

当然了。这里面的颜色都能变的。
但是我不满意它一直在这换颜色不服从我的控制,于是想加一个按钮。但是又不想按钮一直都是一个样子,就是想霓虹灯运行的时候显示”暂停“,暂停的时候显示”开始“,然后问题就来了......
这个霓虹灯怎么弄出来的就不赘述了,也不是重点。
重点是我想把按钮的改变这么写的:
new Timer().schedule(new TimerTask()
{
@Override
public void run()
{
// TODO Auto-generated method stub
<span style="white-space:pre"> </span>if(ToContralTimer % 2 ==1)//这个是我的一个小手段用来判断按了几次按钮然后判断应该显示什么
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>handler.sendEmptyMessage(0x123);
<span style="white-space:pre"> </span>mbutton.setText("暂停");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>mbutton.setText("暂停");
}
},0,200);
Handler只是接受了消息然后改变颜色。(细节不多说了。)
然后悲剧了。
找到了这个

图有点小,内容就是 Only the original thread that created a view hierarchy can touch its views.
看了一下英语,应该是线程的问题,大概意思就是这个view 的东西只有创建它的那个线程才可以改变。也就是说android中相关的view和控件不是线程安全的。
于是想到了将改变Button的text的重担交给Handler。并且查找了资料发现其实Handler默认是在主线程下工作的,那这样就好了~创建也是主线程,这样应该就可以了吧。
于是Handler被改成了这样:
Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
if(msg.what == 0x123)
{
mbutton.setText("暂停");
for(int i = 0; i < names.length ; i++)
{
views[i].setBackgroundResource(colors[(i+currentcolor) % names.length]);
}
currentcolor ++;
}
else if (msg.what == 0x124) {
mbutton.setText("开始");
}
super.handleMessage(msg);
}
};
Timer变成了这样:new Timer().schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
if(ToContralTimer % 2 ==1)
{
handler.sendEmptyMessage(0x123);
}
else
{
handler.sendEmptyMessage(0x124);
}
}
},0,200);
也就是说,我的思路是:既然在Timer的线程中我们不能改变Button的Text,那么就发信号,然后让Handler代替我们完成这个动作就好了。也就是代码中的0x123和0x124”信号“。
于是完成了自己想要的效果!霓虹灯终于听话了!啊哈哈!
最开始这样:

单击开始之后就开始酷炫的变色,然后变成这样:

注意一下按钮的文字变化就好了。。。
然后再单击”暂停“就是上面的那个样子了~
虽然这个例子很简单。
但是还是写了出来为大家提供个参考。其中代码的片段由于是从我的印象笔记搬来的,所以代码风格有问题。
有不当的地方还望多多指教。