关于Android的View线程安全的问题

Android中解决View线程安全问题
这篇博客讲述了作者在实现Android霓虹灯效果时遇到的线程安全问题。当试图在非主线程中更改Button的Text时,遇到了'Only the original thread that created a view hierarchy can touch its views.'的错误。作者通过使用Handler来解决这个问题,确保更改UI的操作在主线程进行,实现了在不同状态下按钮显示不同文字的效果。
先说一下这个问题发现的原因:

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”信号“。

于是完成了自己想要的效果!霓虹灯终于听话了!啊哈哈!

最开始这样:


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


注意一下按钮的文字变化就好了。。。
然后再单击”暂停“就是上面的那个样子了~

虽然这个例子很简单。
但是还是写了出来为大家提供个参考。其中代码的片段由于是从我的印象笔记搬来的,所以代码风格有问题。
有不当的地方还望多多指教。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值