Tencent/QMUI_Android · error · RuntimeException
View is not attached to Activity
Error message
View is not attached to Activity
What it means
ActivityHostModalProvider.provide() walks from the given View up to its rootView and looks up the window's android.R.id.content FrameLayout. If that lookup returns null, the view hierarchy is not an Activity window (e.g. the view lives in a Dialog, or was never attached), so a RuntimeException is thrown because there is no Activity content parent to host the modal.
Source
Thrown at compose/src/main/java/com/qmuiteam/compose/modal/QMUIModal.kt:107
fun doOnShow(listener: Action): QMUIModal
fun doOnDismiss(listener: Action): QMUIModal
fun removeOnShowAction(listener: Action): QMUIModal
fun removeOnDismissAction(listener: Action): QMUIModal
fun interface Action {
fun invoke(modal: QMUIModal)
}
}
fun interface ModalHostProvider {
fun provide(view: View): Pair<FrameLayout, OnBackPressedDispatcher>
}
class ActivityHostModalProvider : ModalHostProvider {
override fun provide(view: View): Pair<FrameLayout, OnBackPressedDispatcher> {
val contentLayout =
view.rootView.findViewById<FrameLayout>(Window.ID_ANDROID_CONTENT) ?: throw RuntimeException("View is not attached to Activity")
val activity = contentLayout.context as? AppCompatActivity ?: throw RuntimeException("view's rootView's context is not AppCompatActivity")
return contentLayout to activity.onBackPressedDispatcher
}
}
val DefaultModalHostProvider = ActivityHostModalProvider()
fun View.qmuiModal(
mask: Color = DefaultMaskColor,
systemCancellable: Boolean = true,
maskTouchBehavior: MaskTouchBehavior = MaskTouchBehavior.dismiss,
uniqueId: Long = SystemClock.elapsedRealtimeNanos(),
modalHostProvider: ModalHostProvider = DefaultModalHostProvider,
enter: EnterTransition = fadeIn(tween(), 0f),
exit: ExitTransition = fadeOut(tween(), 0f),
content: @Composable AnimatedVisibilityScope.(QMUIModal) -> Unit
): QMUIModal {
if (!isAttachedToWindow) {View on GitHub (pinned to 026e7d4866)
Solutions
- Ensure the view passed to the modal API is attached to a normal Activity window (check view.isAttachedToWindow first).
- Pass a view that is a descendant of the Activity's content view, not one hosted in a Dialog/PopupWindow.
- Supply a custom ModalHostProvider that resolves the FrameLayout and OnBackPressedDispatcher for your non-standard host.
- Defer showing the modal until after the Activity content is laid out (e.g. view.post { }).
Example fix
// before
myDialogContentView.qmuiDialog { ... } // throws: not in Activity window
// after
requireNotNull(activity.findViewById<ViewGroup>(android.R.id.content))
activity.contentView.qmuiDialog { ... } Defensive patterns
Strategy: validation
Validate before calling
fun isHostedInActivity(view: View): Boolean = view.isAttachedToWindow && view.rootView.findViewById<ViewGroup>(android.R.id.content) != null
Type guard
fun View.findActivityContent(): FrameLayout? = rootView.findViewById(Window.ID_ANDROID_CONTENT)
Try / catch
try { view.qmuiDialog { ... } } catch (e: RuntimeException) { Log.e(TAG, "modal host unavailable", e) } Prevention
- Only trigger modals from views attached to an Activity window
- Avoid hosting modal-triggering views inside Dialogs/Popups
- Check isAttachedToWindow before calling modal APIs
When it happens
Trigger: Calling qmuiModal/qmuiStillModal (or qmuiBottomSheet/qmuiDialog/qmuiToast) with a view whose rootView does not contain Window.ID_ANDROID_CONTENT — i.e. the view is attached to a non-Activity window (Dialog, PopupWindow, overlay) or the rootView lacks the content frame.
Common situations: Showing a modal from a Dialog or floating window context; view not yet attached so rootView is a temporary parent; using the modal inside a custom presentation or Compose-in-Dialog host.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- View is not attached to window
- view's rootView's context is not AppCompatActivity
- Threshold value should be between 0 and 1.0
- You should config the exposure on parent($parent) for constr
- Can not perform LatestVisitRecord, %s must be annotated by L
AI-assisted analysis of Tencent/QMUI_Android@026e7d4866 (2026-09-06).
Data as JSON: /api/errors/79582a25dc433dca.
Report an issue: GitHub.