java.lang.IndexOutOfBoundsException:试图从RecyclerView中删除URL已损坏



我正在使用Glide加载URL列表,如下所示:

@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) {
isBrokenUrl = true;

arrayList.remove(holder.getBindingAdapterPosition());  //ISSUE IS HERE
notifyItemRangeChanged(holder.getBindingAdapterPosition(), getItemCount());
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
isBrokenUrl = false;
return false;
}
}).into(holder.image);
holder.image.setOnClickListener(v -> itemStringClickListener.onItemClicked(arrayList.get(position)));
}

在列表中有一个损坏的URL,我想从RecyclerView:中删除带有这些损坏URL的项目

arrayList.remove(holder.getBindingAdapterPosition());
notifyItemRangeChanged(holder.getBindingAdapterPosition(), getItemCount());

这是有效的,但如果我滚动得太快,应用程序就会崩溃:

com.bumptech.glide.load.engine.CallbackException: Unexpected exception thrown by non-Glide code
at com.bumptech.glide.load.engine.EngineJob.callCallbackOnLoadFailed(EngineJob.java:175)
at com.bumptech.glide.load.engine.EngineJob$CallLoadFailed.run(EngineJob.java:402)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:7889)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=109; index=-1
at java.util.ArrayList.remove(ArrayList.java:506)
at maa.utils.adapters.SearchedStickersAdapter$1.onLoadFailed(SearchedStickersAdapter.java:63)
at com.bumptech.glide.request.SingleRequest.onLoadFailed(SingleRequest.java:683)
at com.bumptech.glide.request.SingleRequest.onLoadFailed(SingleRequest.java:651)
at com.bumptech.glide.load.engine.EngineJob.callCallbackOnLoadFailed(EngineJob.java:173)
at com.bumptech.glide.load.engine.EngineJob$CallLoadFailed.run(EngineJob.java:402) 
at android.os.Handler.handleCallback(Handler.java:938) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:236) 
at android.app.ActivityThread.main(ActivityThread.java:7889) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:600) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967) 

由于getBindingAdapterPosition返回-1,代码失败。那个观点持有者不受任何立场的约束。你似乎在尝试做一些异步的事情。如果是这样,就不应该将视图持有者或其中的任何视图传递给任何回调。相反,您应该在进行异步调用时传递该索引处的位置和/或数据项,而不是在回调期间查询持有者。这是因为绑定可能在回调发生时和之后发生变化。如果你不这样做,即使当它";作品";它可能对错误的索引执行操作。

事实上,由于您是在onBindViewHolder中执行此操作的,因此在使用它的两个位置都只使用position来替换它应该会使其正常工作。

最新更新