Glide加载URL列表移除RecyclerView失效链接项快速滑动抛IndexOutOfBoundsException如何解决
崩溃根因
快速滑动RecyclerView时,滑出屏幕的item对应的ViewHolder会被系统回收复用,此时Glide的异步加载失败回调才触发,调用holder.getBindingAdapterPosition()会返回RecyclerView.NO_POSITION(固定值为-1),直接用该无效下标操作ArrayList就会抛出数组越界异常。
修复方案
按以下步骤修改代码即可解决:
- 先校验位置有效性再执行删除操作:拿到Adapter位置后,先判断是否不等于
RecyclerView.NO_POSITION,且小于数据源长度,再执行删除逻辑。 - 优化列表通知方法:删除单条item时使用
notifyItemRemoved()替代notifyItemRangeChanged(),性能更高还自带删除动画。 - 修复点击事件的下标取值问题:原有点击事件使用
onBindViewHolder的入参position,该值是绑定时刻的静态值,列表item顺序/数量变化后会取值错误,改为实时调用holder.getBindingAdapterPosition()取值。 - 回收ViewHolder时取消Glide请求:重写Adapter的
onViewRecycled方法,主动取消滑出屏幕item的Glide加载请求,避免无用回调触发。
修改后完整代码
@Override public void onBindViewHolder(@NonNull SearchViewHolder holder, int position) { Glide.with(context) .load(arrayList.get(position)) .diskCacheStrategy(DiskCacheStrategy.ALL) .error(R.drawable.transparent_icon) .override(Constants.THUMBNAIL_SIZE, Constants.THUMBNAIL_SIZE) .fitCenter() .listener(new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { int adapterPos = holder.getBindingAdapterPosition(); // 先校验位置有效性 if (adapterPos != RecyclerView.NO_POSITION && adapterPos < arrayList.size()) { arrayList.remove(adapterPos); notifyItemRemoved(adapterPos); } return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { return false; } }).into(holder.image); holder.image.setOnClickListener(v -> { int clickPos = holder.getBindingAdapterPosition(); if (clickPos != RecyclerView.NO_POSITION && clickPos < arrayList.size()) { itemStringClickListener.onItemClicked(arrayList.get(clickPos)); } }); } // 新增ViewHolder回收时取消Glide请求的逻辑 @Override public void onViewRecycled(@NonNull SearchViewHolder holder) { super.onViewRecycled(holder); Glide.with(context).clear(holder.image); }
注:原代码中定义的isBrokenUrl变量没有实际使用,且作为全局变量存在并发取值问题,可直接删除。
内容的提问来源于stack exchange,提问作者user7954210
相关产品推荐
相关产品推荐

