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
- Validate position: if (position >= 0 && position < adapter.getItemData().size()) before calling replaceItem.
- Compute the index from a stable identifier rather than a stale stored index.
- Clamp or ignore the update when the list shrank, and refresh the adapter instead.
- 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
- Always bounds-check the position against the current data size before replaceItem.
- Avoid caching adapter positions across data mutations; look up by stable id.
- After data changes, refresh/rebind instead of replacing at stale indices.
- Watch off-by-one: valid positions are 0..size-1, never size.
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
- ViewPager with adapter %s requires a view id
- Not support the type: %s
- topView must implement from IQMUIContinuousNestedTopView
- bottomView must implement from IQMUIContinuousNestedBottomVi
- delegateView must be a instance of View
AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06).
Data as JSON: /api/errors/45324886cd183b44.
Report an issue: GitHub.