Tencent/QMUI_Android · error · RuntimeException

already exist the theme item for

Error message

already exist the theme item for 

What it means

QMUISkinManager.addSkin() throws when a skin is already registered for the same non-default index with a DIFFERENT style resource. Registering the identical style for the same index silently returns, but changing the style under an existing index is rejected to prevent silently redefining themes.

Source

Thrown at qmui/src/main/java/com/qmuiteam/qmui/skin/QMUISkinManager.java:251

    public Resources.Theme getCurrentTheme() {
        SkinItem skinItem = mSkins.get(mCurrentSkin);
        if (skinItem != null) {
            return skinItem.getTheme();
        }
        return null;
    }

    @MainThread
    public void addSkin(int index, int styleRes) {
        if (index <= 0) {
            throw new IllegalArgumentException("index must greater than 0");
        }
        SkinItem skinItem = mSkins.get(index);
        if (skinItem != null) {
            if (skinItem.getStyleRes() == styleRes) {
                return;
            }
            throw new RuntimeException("already exist the theme item for " + index);
        }
        skinItem = new SkinItem(styleRes);
        mSkins.append(index, skinItem);
    }

    static ViewSkinCurrent getViewSkinCurrent(View view) {
        Object current = view.getTag(R.id.qmui_skin_current);
        if (current instanceof ViewSkinCurrent) {
            return (ViewSkinCurrent) current;
        }
        return null;
    }

    public void dispatch(View view, int skinIndex) {
        if (view == null) {
            return;
        }
        if (QMUIConfig.DEBUG) {

View on GitHub (pinned to 026e7d4866)

Solutions

  1. Register each skin index exactly once (guard with a boolean or check during initialization).
  2. Call removeSkin(index) before re-registering an index with a different style.
  3. Make style resources stable per index — do not swap styles under an existing index.
  4. Use distinct increasing indices for new skins instead of reusing indices.

Example fix

// before
skinManager.addSkin(1, R.style.Skin_Blue);
skinManager.addSkin(1, R.style.Skin_Dark); // throws

// after
skinManager.removeSkin(1);
skinManager.addSkin(1, R.style.Skin_Dark);
Defensive patterns

Strategy: validation

Validate before calling

if (skinIndexOf(styleRes) != index || isFirstRegistration) {
    skinManager.addSkin(index, styleRes);
}

Try / catch

try {
    skinManager.addSkin(index, styleRes);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("already exist")) {
        skinManager.removeSkin(index);
        skinManager.addSkin(index, styleRes);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling addSkin(index, styleRes) twice for the same index with different styleRes values, e.g. rebuilding the skin table on every Activity start or after calling install() again.

Common situations: Re-running skin registration code in onCreate/onResume without an idempotency check; refactoring renamed a skin style so the old index now maps to a new style; two modules each register skins into shared index numbers.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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