Tencent/QMUI_Android · error · IllegalAccessException

替换数据不存在

Error message

替换数据不存在

What it means

QMUIItemViewsAdapter.replaceItem validates that the given position is within 0..size-1 of mItemData; otherwise it throws IllegalAccessException with the Chinese message meaning 'replacement data does not exist'. The odd exception type is a legacy API choice, but the condition is simply an out-of-range index.

Source

Thrown at qmui/src/main/java/com/qmuiteam/qmui/widget/QMUIItemViewsAdapter.java:138

        mParentView.requestLayout();

    }

    public T getItem(int position) {
        if (mItemData == null) {
            return null;
        }
        if (position < 0 || position >= mItemData.size()) {
            return null;
        }
        return mItemData.get(position);
    }

    public void replaceItem(int position, T data) throws IllegalAccessException {
        if (position < mItemData.size() && position >= 0) {
            mItemData.set(position, data);
        } else {
            throw new IllegalAccessException("替换数据不存在");
        }

    }

    protected abstract void bind(T item, V view, int position);

    public List<V> getViews() {
        return mViews;
    }

    public int getSize() {
        if (mItemData == null) {
            return 0;
        }
        return mItemData.size();
    }
}

View on GitHub (pinned to 026e7d4866)

Solutions

  1. Validate position: if (position >= 0 && position < adapter.getItemData().size()) before calling replaceItem.
  2. Compute the index from a stable identifier rather than a stale stored index.
  3. Clamp or ignore the update when the list shrank, and refresh the adapter instead.
  4. Catch IllegalAccessException around replaceItem as a guard if the data size can change concurrently.

Example fix

// before
viewsAdapter.replaceItem(position, newData); // may throw if position stale
// after
if (position >= 0 && position < viewsAdapter.getItemData().size()) {
    viewsAdapter.replaceItem(position, newData);
}
Defensive patterns

Strategy: validation

Validate before calling

if (position < 0 || position >= adapter.getItemData().size()) return;
adapter.replaceItem(position, data);

Try / catch

try {
    adapter.replaceItem(position, data);
} catch (IllegalAccessException e) {
    Log.w(TAG, "stale position " + position + " for replaceItem", e);
}

Prevention

When it happens

Trigger: Calling replaceItem(position, data) with a negative position or a position >= mItemData.size(), e.g. replacing item at an index that was removed, or using a RecyclerView adapter position after data was cleared.

Common situations: Updating a tab/badge item after data shrink, off-by-one when using size as index, or stale positions captured before the adapter's data changed.

Related errors


AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06). Data as JSON: /api/errors/45324886cd183b44. Report an issue: GitHub.