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

写代码的时候碰到android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.这个异常。
异常的意思是说只有创建这个view的线程才能操作这个view,普通会认为是将view创建在非UI线程中才会出现这个错误。
可是在我代码中将view创建在UI线程中也会出现这个错误

下面是我出错的代码:

AsyncTask<Void, Void, Void> myTask = new AsyncTask<Void, Void, Void>(){
    		ProgressDialog progressDialog;
			@Override
			protected void onPreExecute() {
				super.onPreExecute();
				progressDialog = new ProgressDialog(getContext());
				progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				progressDialog.setMessage("请稍后...");
				progressDialog.show();
			}

			@Override
			protected Void doInBackground(Void... params) {
				//耗时操作...
				return null;
			}

			@Override
			protected void onPostExecute(Void result) {
				super.onPostExecute(result);
				progressDialog.dismiss();

			}
    	};
    	myTask.execute();

  如上,将progressDialog创建在UI进程中还会出现以上错误。

最后在仔细检查时,发现在doInBackground方法里调用了view.invalidate();这个方法。

调用这个方法会调用view的onDraw();方法,从而引起窗口重绘,自然原本的UI进程也被破坏。等到执行完doInBackground后,再调用onPostExecute这个方法执行progressDialog.dismiss();时已经找不到原本创建它的UI进程,自然就会报android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.这个错误了。

另外, 一般引起invalidate()操作的函数如下:

1、直接调用invalidate()方法,请求重新draw(),但只会绘制调用者本身。

2、setSelection()方法 :请求重新draw(),但只会绘制调用者本身。

3、setVisibility()方法 : 当View可视状态在INVISIBLE转换VISIBLE时,会间接调用invalidate()方法,

继而绘制该View。

4 、setEnabled()方法 : 请求重新draw(),但不会重新绘制任何视图包括该调用者本身。

查阅这个异常的相关信息时,发现另外一种情况也可能导致这个异常:

http://my.oschina.net/qixiaobo025/blog/195396

时间: 2024-08-08 16:52:20

Only the original thread that created a view hierarchy can touch its views异常的相关文章

Android: Only the original thread that created a view hierarchy can touch its views 异常

最近自己再写一个小项目练手,创建一个线程从网络获取数据然后显示在 recyclerView 上.写好后发现页面能够显示,但是有时候会把请求的数据显示过来,有时候不会.点开 android monitor 一看,有一个提示 : Only the original thread that created a view hierarchy can touch its views. 异常的意思是说只有创建这个view的线程才能操作这个 view,普通会认为是将view创建在非UI线程中才会出现这个错误.

错误:Only the original thread that created a view hierarchy can touch its views——Handler的深入解析

这个错误很常见,基本上写线程操作都遇到过这个错误.根本原因是view控件的线程安全问题,通俗点讲就是所有的更新UI操作都需要在主线程(也就是UI线程中完成),而不能在新开的子线程中操作. 基本思路:既然子线程需要更新UI,但子线程自身又不能完成任务,所以只能通过建立一个通信机制,当子线程需要更新UI时,发消息通知主线程并将更新UI的任务post给主线程,让主线程来完成分内的UI更新操作.这个机制是什么呢?就是Handler.Handler 从属于谁?当然是主线程.每个线程都有自己的handler

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. * 说明: * 自定义view的时候出现这个错误,是用错了方法. * * 2016-6-15 深圳 南山平山村 曽剑锋 ****************************

浅析Android中的消息机制-解决:Only the original thread that created a view hierarchy can touch its views.

在分析Android消息机制之前,我们先来看一段代码: [html] view plaincopyprint? public class MainActivity extends Activity implements View.OnClickListener { private TextView stateText; private Button btn; @Override public void onCreate(Bundle savedInstanceState) { super.onC

&quot;Only the original thread that created a view hierarchy can touch its views.&quot;解决

Android系统中的视图组件并不是线程安全的,如果要更新视图,必须在主线程中更新,不可以在子线程中执行更新的操作.所以可以依靠消息机制来进行更新. 先声明一个handler来处理消息 private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { setContentView(child); } }; 然后在视图中触发的事件的方法中发送消息到handler来触发更新视图 b

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

1 runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Log.i(tag, "will-success-update"); adapter.addItem((Will)reason); } }); Done

&quot;Only the original thread that created a view hierarchy can touch its views.” 解决方法

这个主要总是,开启的线程和 UI 线程(主线程)不是同一个线程.可以Runnable方式避免,如下例所示就可以解决这个问题了. public static void updateText(Activity act, resID) { loadingText = (TextView) activity.findViewById(R.id.loadingScreenTextView); act.runOnUiThread(new Runnable() { public void run() { lo

only the original thread that created a view

本来准备写一个简单的通过url获取网络图片setimage到imageview上去 没想到还是有一些小bug 先把源码供上 package com.example.seturlbitmapdemo; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL;

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a vi

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views 这个错误相信大家一定不陌生,特别是刚学习android时,会引起的错误,意思是指在子线程中对UI做了操作,现在写个简单的demo: public class MainActivity extends Activity { privat