Tencent/QMUI_Android · error · IllegalStateException

FragmentScheme#activities must be QMUIFragmentActivity.

Error message

FragmentScheme#activities must be QMUIFragmentActivity.

What it means

After the emptiness check, generateFragmentHostActivityList verifies each entry of FragmentScheme#activities is a subclass of QMUIFragmentActivity. Any entry that is not throws this IllegalStateException, since generated scheme code launches the fragment through QMUIFragmentActivity.

Source

Thrown at arch-compiler/src/main/java/com/qmuiteam/qmui/arch/SchemeProcessor.java:399

        CodeBlock.Builder builder = CodeBlock.builder();
        TypeMirror[] activities = null;
        try {
            fragmentScheme.activities();
        } catch (MirroredTypesException mte) {
            List<? extends TypeMirror> containerMirrors = mte.getTypeMirrors();
            activities = new TypeMirror[containerMirrors.size()];
            for (int i = 0; i < activities.length; i++) {
                activities[i] = containerMirrors.get(i);
            }
        }
        if(activities == null || activities.length == 0){
            throw new IllegalStateException("FragmentScheme#activities can not be empty.");
        }
        builder.add("new $T[]{", OriginClassName);
        for(int i=0; i < activities.length; i++){
            TypeMirror item = activities[i];
            if(!isSubtypeOfType(item, QMUI_FRAGMENT_ACTIVITY_TYPE)){
                throw new IllegalStateException("FragmentScheme#activities must be QMUIFragmentActivity.");
            }
            if(i > 0){
                builder.add(",");
            }
            builder.add("$T.class", ClassName.get(item));
        }
        builder.add("}");
        return builder.build();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> types = new LinkedHashSet<>();
        types.add(ActivityScheme.class.getCanonicalName());
        types.add(FragmentScheme.class.getCanonicalName());
        return types;
    }

View on GitHub (pinned to 026e7d4866)

Solutions

  1. Make every listed activity extend QMUIFragmentActivity.
  2. Replace non-QMUI hosts in the activities array with your QMUIFragmentActivity subclass (e.g. MainActivity : QMUIFragmentActivity()).
  3. Remove any entries that are fragments or non-host classes.

Example fix

// before
@FragmentScheme(name = "page", activities = [PlainActivity::class]) // PlainActivity : AppCompatActivity

// after
class PlainActivity : QMUIFragmentActivity() { ... }
@FragmentScheme(name = "page", activities = [PlainActivity::class])
Defensive patterns

Strategy: validation

Validate before calling

fun validateHostActivities(activities: List<Class<*>>) =
    activities.forEach {
        check(QMUIFragmentActivity::class.java.isAssignableFrom(it)) { "$it must be QMUIFragmentActivity" }
    }

Type guard

fun isQMUIFragmentActivity(cls: Class<*>): Boolean =
    QMUIFragmentActivity::class.java.isAssignableFrom(cls)

Prevention

When it happens

Trigger: Passing an Activity class to activities that does not extend QMUIFragmentActivity — e.g. a plain AppCompatActivity, another custom activity base class, or a Fragment mistakenly listed.

Common situations: Migrating from plain AppCompatActivity hosts to QMUI; pointing activities at the wrong class after refactor; listing multiple hosts where only one extends QMUIFragmentActivity.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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