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
- Move registerEffect calls into onAttach or later lifecycle callbacks (onViewCreated/onResume)
- Check isAdded()/getActivity() != null before calling
- 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
- Never call registerEffect from constructors or field initializers
- Register effects in onAttach/onViewCreated, unregister in onDetach/onDestroyView
- Guard async callbacks with isAdded()
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
- Can not perform LatestVisitRecord, %s must be annotated by L
- Can not find the fragment container provider.
- requestCode can not be %s
- %s did not call through to super.shouldPreventSwipeBack()
- %s did not call through to super.onEnterAnimationStart(Anima
AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06).
Data as JSON: /api/errors/3ab156086f177c5d.
Report an issue: GitHub.