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);
        }
    };
复制代码

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

posted @   huansky  阅读(28785)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示