zoukankan      html  css  js  c++  java
  • 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 = "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());
                            ......解析数据
                            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);
            }
        };

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

  • 相关阅读:
    JavaWeb
    申请百度开发者账号
    秋招C++面试相关总结索引
    游戏开发客户端
    Python源码剖析——02虚拟机
    Python源码剖析——01内建对象
    Pymongo 笔记
    调用其他文件__name__=='__main__'下代码
    Python 相关
    Python import本地模块
  • 原文地址:https://www.cnblogs.com/huansky/p/7784941.html
Copyright © 2011-2022 走看看