You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

判断URL有效时添加项到RecyclerView出现子线程操作UI错误如何解决

问题原因

Android 规定所有UI相关的操作都必须在主线程(也就是创建View层级的原始线程)执行,你在自定义的子线程中调用了adapter.notifyItemChanged(0),这个方法属于RecyclerView的UI更新操作,不符合线程要求,所以抛出了ViewRootImpl$CalledFromWrongThreadException异常。
另外你代码里thread.currentThread().interrupt()属于冗余逻辑,没有实际作用还会打断当前线程,建议删除。同时你新增条目调用notifyItemChanged是错误的,该方法用于更新已有条目,新增条目应该调用notifyItemInserted。

解决方案

你只需要把UI更新的逻辑切换到主线程执行即可,常用实现方式如下:

方式1:使用Activity的runOnUiThread方法(推荐,适用于在Activity中调用的场景)

修改子线程中调用InsertItem的逻辑:

if(code == 200) {
    Log.d(TAG, "reachable");
    // 切换到主线程执行插入操作
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            InsertItem(url,adapter);
        }
    });
}

修改InsertItem方法:

private void InsertItem(URL url, MyAdapter adapter) {
    arrayList.add(0,new file(url.toString()));
    // 新增条目调用notifyItemInserted
    adapter.notifyItemInserted(0);
}

方式2:使用绑定主线程Looper的Handler(适用于非Activity场景)

首先在主线程中初始化Handler:

// 该代码需要在主线程执行
private Handler mainHandler = new Handler(Looper.getMainLooper());

修改子线程中调用InsertItem的逻辑:

if(code == 200) {
    Log.d(TAG, "reachable");
    // 向主线程提交任务
    mainHandler.post(new Runnable() {
        @Override
        public void run() {
            InsertItem(url,adapter);
        }
    });
}

InsertItem方法的修改和方式1一致。

内容的提问来源于stack exchange,提问作者ghazalia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 18:06:04