运行时报 android.view.ViewRootImpl$CalledFromWrongThreadException:错误
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
原因操作阻塞了UI线程 或者 在工作线程中操作了UI元素
知道原因就好解决了:
在工作线程中更新UI的三种方法:
1. Activity.runOnUiThread(Runnable) ;
2. Handler(sendMessage(Message) or post(Runnable));
3. AsyncTask ;
出现种错误一般是在使用第三方方法时,没有注意是不是UI线程 所导致的!个人比较喜欢 runOnUiThread() 来解决。
当应用程序启动,创建了一个叫“main”的线程,用于管理UI相关,又叫UI线程。其他线程叫工作线程(Work Thread)。
Single Thread Model
两个原则
在工作线程更新UI方法
例子程序
HandlerActivity01主要代码:
Java代码
这是一种错误的做法,运行程序,会报错误:
HandlerActivity02主要代码:
这里有个容易出错的地方,在更新UI方法2和3中,我们传入的参数是一个Runnable对象,一般认为这就会启动一个新的线程,而且常有人在这个Runnable对象的run方法中进行耗时操作。看过这块的源码就会知道,其实,android只是调用了这个Runnable对象的run方法而已,并没有启动新的线程,而且我们不应该在run方法中进行耗时操作,因为这个run方法最终是在UI线程里面执行的。也就是说,run方法里面只应该放更新UI的代码,handleMessage方法也一样。
如果你要看这部分源代码的话,相信这个图对你会有帮助:
HandlerActivity03主要代码:
这个方法确实挺好,因为它为你封装了许多操作,你只需要记住在doInBackground方法中写耗时操作的代码,在onPostExecute方法中写更新UI的方法就行了。