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线程中才会出现这个错误。

本来我想将就下,能看到算了的,说明我会简单使用 fragment 了。不过作为程序员我们肯定要寻根问底的啊。

这段请求数据代码如下所示:

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String url = "";
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder().url(url).method("GET", null).build();
                    okhttp3.Response response = client.newCall(request).execute();
                    if (response.isSuccessful()) {
                        String responseString = (response.body() == null ? "" : response.body().string());
                        ......解析数据
                        WidgetActionEvent event = new WidgetActionEvent(WidgetActionEvent.ACTION_CLICK);
                        event.object = feedModel;
                        EventBus.getDefault().post(event);
                        //iLoadData.loadData(feedModel);

                    } else {
                        Log.i(TAG, "okHttp is request error");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

数据请求之后,解析,并采用 eventbus 来传送数据。

ps :如果你是在 mainActivity 中调用上述代码,是不会产生的异常的,因为都是运行在主线程中。

变形一  : 崩溃

于是我换了一种形式来传递数据,这次采用回调的方式,也就是上面被注释掉的那行代码:

iLoadData.loadData(feedModel);

这次不用 eventbus 竟然崩溃了......我能怎么办,我也很无奈啊。

FATAL EXCEPTION: Thread-932
Process: example.hope.mvpwithrecyclerview, PID: 4916
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

解决办法:采用 handle

实现代码如下:

   /**
     * 发起网络请求
     */
    public static void okHttp_synchronousGet(final Handler handler) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String url = "http://eff.baidu.com:8086/action/combined/action_RetData.php?name=shenjiaqi";
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder().url(url).method("GET", null).build();
                    okhttp3.Response response = client.newCall(request).execute();
                    if (response.isSuccessful()) {
                        String responseString = (response.body() == null ? "" : response.body().string());
                        ......解析数据
                        handler.sendMessage(handler.obtainMessage(22, feedModel));
                    } else {
                        Log.i(TAG, "okHttp is request error");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

然后再 fragment 添加下面代码用来处理传过来的数据:

   /**
     * 接收解析后传过来的数据
     */
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Object model = (Object) msg.obj;
            showPictures(model);
        }
    };

这样就能后完美的解决这个问题了。

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

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异常

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

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

错误: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

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

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

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

"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