gyf-dev/ImmersionBar · error · IllegalArgumentException
Owner must be attached to a Window.
Error message
Owner must be attached to a Window.
What it means
BarConfig reads window/system-bar metrics, and requireWindow is a null-check guard on the Window passed to it. It throws IllegalArgumentException("Owner must be attached to a Window.") when the supplied Window reference is null, i.e. the owner (Activity/Dialog) has not finished attaching yet.
Solutions
- Defer BarConfig creation until the Activity window exists (after onCreate / in onResume or onViewCreated)
- Null-check activity.getWindow() before constructing BarConfig and skip/retry the measurement
- For dialogs, run config setup in onAttachedToWindow or after show()
Example fix
// before
BarConfig config = new BarConfig(getActivity().getWindow()); // NPE-ish before attach
// after
Window w = getActivity() != null ? getActivity().getWindow() : null;
if (w != null) {
BarConfig config = new BarConfig(w);
} Defensive patterns
Strategy: validation
Validate before calling
if (activity != null && activity.getWindow() != null) { new BarConfig(activity.getWindow()); } Type guard
Window safeWindow(Activity a) { return a == null ? null : a.getWindow(); } Try / catch
try { config = new BarConfig(window); } catch (IllegalArgumentException e) { config = null; /* defer measurement */ } Prevention
- Create BarConfig only after attach (onViewCreated/onResume)
- For dialogs, wait for onAttachedToWindow/show()
- Never measure bars from constructors or before onCreate finishes
When it happens
Trigger: Constructing BarConfig with activity.getWindow() or dialog.getWindow() that returns null — typically before onCreate/onAttachedToWindow completes or after the window is destroyed.
Common situations: Measuring bar insets in Fragment.onCreate or a constructor instead of onViewCreated/onActivityCreated; querying config after activity finish/rotation teardown; a Dialog shown before it has a window.
Related errors
- Fragment must be attached to an Activity.
- Fragment请实现ImmersionOwner接口
- Fragment请实现SimpleImmersionOwner接口
- View参数不能为空
- tag不能为空
AI-assisted analysis of gyf-dev/ImmersionBar@8cac10cd83 (2026-09-08).
Data as JSON: /api/errors/8393c043b614d8df.
Report an issue: GitHub.
Appendix: source
Thrown at immersionbar/src/main/java/com/gyf/immersionbar/BarConfig.java:119
Resources res = context.getResources();
mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
mSmallestWidthDp = getSmallestWidthDp(window);
mStatusBarHeight = getStatusBarHeight(window);
mStatusBarVisible = isStatusBarVisible(window);
mActionBarHeight = getActionBarHeight(window);
mNavigationBarVisible = navigationBarVisibleHint != null ? navigationBarVisibleHint : isNavigationBarVisible(window);
mNavigationBarHeight = getNavigationBarHeight(window, mNavigationBarVisible);
int navigationBarHeightIgnoringVisibility = getNavigationBarHeightIgnoringVisibility(window);
mNavigationBarHeightIgnoringVisibility = navigationBarHeightIgnoringVisibility > 0 ? navigationBarHeightIgnoringVisibility : (mNavigationBarVisible ? mNavigationBarHeight : 0);
mNavigationBarWidth = getNavigationBarWidth(window);
mHasNavigationBar = (mNavigationBarHeight > 0);
mNavigationAtBottom = computeNavigationAtBottom(window);
}
@NonNull
private static Window requireWindow(Window window) {
if (window == null) {
throw new IllegalArgumentException("Owner must be attached to a Window.");
}
return window;
}
/**
* 计算导航栏是否在底部。
* android 11(API 30)起WindowInsets可用,优先用其实际方向判断(底部有inset即在底部,否则在侧边),
* 比老的“手机横屏导航栏在侧边”启发式更准;insets不可用或低版本时回退到原启发式。
*
* @param window window
* @return true表示导航栏在底部,false表示在侧边
*/
private boolean computeNavigationAtBottom(Window window) {
if (Build.VERSION.SDK_INT >= Version.R) {
Insets navInsets = getNavigationBarInsets(window);
if (navInsets != null && (navInsets.bottom > 0 || navInsets.left > 0 || navInsets.right > 0)) {
return navInsets.bottom > 0;
}View on GitHub (pinned to 8cac10cd83)