Tencent/QMUI_Android · error · RuntimeException

Fragment(%s) not attached to Activity.

Error message

Fragment(%s) not attached to Activity.

What it means

registerEffect requires the fragment to be attached to an Activity because the effect registry is tied to the activity context. If getActivity() returns null the library throws rather than silently dropping the registration.

Source

Thrown at arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java:315

    public final void onLatestVisitArgumentChanged() {
        if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.INITIALIZED) && sLatestVisitFragmentUUid == mUUid) {
            checkLatestVisitRecord();
        }
    }

    @Override
    public void onCollectLatestVisitArgument(RecordArgumentEditor editor) {

    }


    @Nullable
    public <T extends Effect> QMUIFragmentEffectRegistration registerEffect(
            @NonNull final LifecycleOwner lifecycleOwner,
            @NonNull final QMUIFragmentEffectHandler<T> effectHandler) {
        FragmentActivity activity = getActivity();
        if (activity == null) {
            throw new RuntimeException("Fragment(" + getClass().getSimpleName() + ") not attached to Activity.");
        }
        ensureFragmentEffectRegistry();
        return mFragmentEffectRegistry.register(lifecycleOwner, effectHandler);
    }

    public <T extends Effect> void notifyEffect(T effect) {
        FragmentActivity activity = getActivity();
        if (activity == null) {
            QMUILog.d(TAG, "Fragment(" + getClass().getSimpleName() + ") not attached to Activity.");
            return;
        }
        ensureFragmentEffectRegistry();
        mFragmentEffectRegistry.notifyEffect(effect);
    }

    private void ensureFragmentEffectRegistry() {
        if (mFragmentEffectRegistry == null) {
            QMUIFragmentContainerProvider provider = findFragmentContainerProvider(false);

View on GitHub (pinned to 026e7d4866)

Solutions

  1. Move registerEffect calls into onAttach or later lifecycle callbacks (onViewCreated/onResume)
  2. Check isAdded()/getActivity() != null before calling
  3. Re-register in onViewCreated instead of constructor or field initializer

Example fix

// before
private QMUIFragmentEffectRegistration reg = registerEffect(this, handler);
// after
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    reg = registerEffect(this, handler);
}
Defensive patterns

Strategy: validation

Validate before calling

if (isAdded() && getActivity() != null) { registerEffect(this, handler); }

Type guard

boolean canRegisterEffect(Fragment f) { return f.isAdded() && f.getActivity() != null; }

Try / catch

try { registerEffect(this, handler); } catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().contains("not attached")) { /* defer to onViewCreated */ } else { throw e; } }

Prevention

When it happens

Trigger: Calling registerEffect(...) before onAttach completes (e.g. in the fragment constructor or onCreate before attachment) or after onDetach.

Common situations: Registering effects in field initializers or constructors; registering in onActivityCreated timing assumptions broken by lifecycle changes; registering after detach during config changes.

Related errors


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