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

Android集成WordPress API排序时ArrayIndexOutOfBoundsException求助

问题:RecyclerView切换排序时出现ArrayIndexOutOfBoundsException异常

加载完12篇文章滚动到底部后,点击「最多浏览」「最多评论」等排序按钮,出现如下异常:

java.lang.ArrayIndexOutOfBoundsException: length=22; index=-1
        at java.util.ArrayList.remove(ArrayList.java:506)
        at com.testtest.test.PostAdapter.showHideProgress(PostAdapter.java:158)
        at com.testtest.test.MainActivity$7.onResponse(MainActivity.java:293)

相关代码

PostAdapter核心代码

private List<Model> dataset;
// ... 其他成员变量

public void clearApplications() {
    int size = this.dataset.size();
    if (size > 0) {
        for (int i = 0; i < size; i++) {
            dataset.remove(0);
        }
        this.notifyItemRangeRemoved(0, size);
    }
}

void showHideProgress(boolean shouldShowProgress){
    if (shouldShowProgress){
        dataset.add(new Model("progress","","","","","","","","","",""));
        Handler handler = new Handler();
        final Runnable r = new Runnable() {
            public void run() {
                notifyItemInserted(dataset.size()-1);
            }
        };
        handler.post(r);
    }else {
        dataset.remove(dataset.size()-1);
        notifyItemRemoved(dataset.size()-1);
    }
}

// ... 其他方法

排序按钮触发代码

if (id == R.id.action_view) {
    adapter.clearApplications();
    yourURL = baseURL + mostView;
    getRetrofit();
    tv.setVisibility(View.VISIBLE);
    return true;
}

尝试过的修改

修改了clearApplications方法,但问题未解决:

public void clearApplications() {
    int size = this.dataset.size() -1;
    if (size > 0) {
        for (int i = 0; i < size; i++) {
            dataset.remove(0);
        }
        this.notifyItemRangeRemoved(0, size);
    }
}

解决方案

1. 修复showHideProgress数组越界问题

异常根源是切换排序后,旧的网络请求回调执行showHideProgress(false)时,列表已被清空,导致dataset.size()-1为-1。添加判断避免越界:

void showHideProgress(boolean shouldShowProgress){
    if (shouldShowProgress){
        // 避免重复添加progress item
        if(!dataset.isEmpty() && "progress".equals(dataset.get(dataset.size()-1).title)){
            return;
        }
        dataset.add(new Model("progress","","","","","","","","","",""));
        notifyItemInserted(dataset.size()-1);
    }else {
        // 列表为空或最后一个不是progress时直接返回
        if(dataset.isEmpty() || !"progress".equals(dataset.get(dataset.size()-1).title)){
            return;
        }
        dataset.remove(dataset.size()-1);
        notifyItemRemoved(dataset.size()); // remove后size已减1,用当前size作为移除位置
    }
}

2. 优化clearApplications方法

循环移除第一个元素效率极低,直接清空列表并通知更新:

public void clearApplications() {
    int size = dataset.size();
    if (size > 0) {
        dataset.clear();
        notifyItemRangeRemoved(0, size);
    }
}

3. 切换排序时取消未完成的网络请求

避免旧请求回调触发无效操作,用Retrofit的话保存当前请求并取消:

// 全局保存当前请求
private Call<List<Model>> currentRequest;

// 触发排序的方法中
if(currentRequest != null && !currentRequest.isCanceled()){
    currentRequest.cancel();
}
currentRequest = apiService.getPosts(yourURL);
currentRequest.enqueue(new Callback<List<Model>>() {
    // ... 回调逻辑
});

4. 修正ViewType识别逻辑

当前代码未处理progress类型的item,导致RecyclerView无法正确加载布局,补充逻辑:

@Override
public int getItemViewType(int position){
    // 计算真实数据位置,排除广告项
    int realPos = position - (position / LIST_AD_DELTA);
    if(realPos >= dataset.size()){
        return viewTypeData;
    }
    Model model = dataset.get(realPos);
    if("progress".equals(model.title)){
        return viewTypeProgress;
    }
    if (position > 0 && position % LIST_AD_DELTA == 0) {
        return AD;
    }
    return viewTypeData;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:20:27