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
更多相关文章
- 第3.3.1节 处理手势操作
- android线程池原理和实现
- Android ListView动画实现方法
- ADB连接Android设备的三种方法
- [Android设计模式]Android退出应用程序终极方法
- Android通过Alpha实现渐变效果的几个方法