Android常见报错之 - Only the original thread that created a view hierarchy can touch its views.

     Only the original thread that created a view hierarchy can touch its views.

     这个报错的原因一般是因为在子线程中直接操作UI导致的(eg, setText())。因为Android中相关的view和控件操作都不是线程安全的,所以Android禁止在非UI线程更新UI。
    ps. 这里所指的操作一般是能会导致控件重绘(invalidate)的操作,在子线程执行setTextColor此类UI操作不会报错

     那么,如果子线程有需要操作UI的需求怎么办呢?一般来说,可以通过如下几种方式来实现。其原理都是通过间接调用,在主线程中去操作UI:

    1. 使用View.post方法,post一个Runnable对象,在run方法中操作UI                                 

final String text = Thread.currentThread().getId() + "_" + i++;
final TextView txtTime1 = (TextView)mainActivity.findViewById(R.id.txtTime1);
txtTime1.post(new Runnable() {
    @Override
    public void run() {
	txtTime1.setText("[View.post]" + text);
    }
});

   2. 使用Activity.runOnUiThread方法,传入一个Runnable对象,在run方法中操作UI       

final TextView txtTime2 = (TextView)mainActivity.findViewById(R.id.txtTime2);
mainActivity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
	txtTime2.setText("[Activity.runOnUiThread]");
    }
});

  3. 在Activity中创建一个Handler对象,在子线程中通过handle.post方法,传入一个Runnable对象,在run方法中操作UI       

final TextView txtTime4 = (TextView)mainActivity.findViewById(R.id.txtTime4);
mainActivity.mHandler.post(new Runnable() {
    @Override
    public void run() {
	txtTime4.setText("[Handler.post]" + text);
    }
});

  4. 在Activity中创建一个Handler对象,并且在handlerMessage方法中针对指定的消息去操作UI,而消息则是有子线程通过handler.sendMessage方法发送
      1)在Activity的onCreate方法中创建一个Handler对象,并在收到自定义消息UPDATE_TIME_ID之后操作UI

mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
	super.handleMessage(msg);
	if (msg.what == UPDATE_TIME_ID) {
		String strTime = msg.getData().getString(UPDATE_TIME_KEY);
		((TextView)findViewById(R.id.txtTime3)).setText(strTime);
	} 
    }
};

        2) 在子线程中通过handler.sendMessage方法发送ID为UPDATE_TIME_ID的消息

Message updateTimeMessage = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString(UPDATE_TIME_KEY, "[Handle.sendMessage]" + text);
updateTimeMessage.what = MainActivity.UPDATE_TIME_ID;
updateTimeMessage.setData(bundle);
mainActivity.mHandler.sendMessage(updateTimeMessage);

 

 参考:

    https://www.cnblogs.com/lao-liang/p/5108745.html

 

 

 

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值