判断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
相关产品推荐
相关产品推荐

