AvaloniaUI/Avalonia · error · InvalidOperationException

Activity.Window must be set.

Error message

Activity.Window must be set.

What it means

AndroidInsetsManager reads the Activity's Window via a property that throws if Window is null. Activity.getWindow() is null until the Activity has a window attached (after super.onCreate and setContentView). Accessing Window before that point (e.g. during early init or on a not-yet-attached activity) triggers the exception.

Source

Thrown at src/Android/Avalonia.Android/Platform/AndroidInsetsManager.cs:34

namespace Avalonia.Android.Platform
{
    internal sealed class AndroidInsetsManager : WindowInsetsAnimationCompat.Callback, IInsetsManager, IOnApplyWindowInsetsListener, ViewTreeObserver.IOnGlobalLayoutListener, IInputPane
    {
        private readonly Activity _activity;
        private readonly TopLevelImpl _topLevel;
        private bool _displaysEdgeToEdge;
        private bool? _systemUiVisibility;
        private SystemBarTheme? _statusBarTheme;
        private bool? _isDefaultSystemBarLightTheme;
        private Color? _systemBarColor;
        private InputPaneState _state;
        private Rect _previousRect;
        private Insets? _previousImeInset;
        private bool _displayEdgeToEdgePreference;
        private readonly bool _usesLegacyLayouts;
        private readonly bool _isDisplayEdgeToEdgeForced;

        private AndroidWindow Window => _activity.Window ?? throw new InvalidOperationException("Activity.Window must be set."); 
        
        public event EventHandler<SafeAreaChangedArgs>? SafeAreaChanged;
        public event EventHandler<InputPaneStateEventArgs>? StateChanged;

        public InputPaneState State
        {
            get => _state; set
            {
                var oldState = _state;
                _state = value;

                if (oldState != value && Build.VERSION.SdkInt <= BuildVersionCodes.Q)
                {
                    var currentRect = OccludedRect;
                    NotifyStateChanged(value, _previousRect, currentRect, TimeSpan.Zero, null);
                    _previousRect = currentRect;
                }
            }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Access Window only after Activity.Attach/onCreate and setContentView have run (post super.OnCreate).
  2. Defer insets operations to OnAttachedToWindow / OnResume where Window is guaranteed set.
  3. Guard the access: `if (_activity.Window is null) return;` at call sites instead of throwing in the property.
  4. Ensure the insets manager is constructed after the activity has a window.

Example fix

// before
private AndroidWindow Window => _activity.Window ?? throw new InvalidOperationException("Activity.Window must be set.");

// after (nullable property; callers guard)
private AndroidWindow? WindowOrNull => _activity.Window;

private AndroidWindow Window => WindowOrNull
    ?? throw new InvalidOperationException(
        "Activity.Window is null; call insets APIs only after OnCreate/setContentView (e.g. in OnResume or OnAttachedToWindow).");
Defensive patterns

Strategy: validation

Validate before calling

// only resolve Window once the activity has one
if (_activity.Window is null) return;

Type guard

static bool HasWindow(Activity a) => a.Window is not null;

Try / catch

// guard at call sites instead of catching; move insets work to OnResume/OnAttachedToWindow.

Prevention

When it happens

Trigger: Calling any AndroidInsetsManager API that resolves Window (SafeArea, edge-to-edge, system bars) before the Activity's Window is set — i.e. before onCreate completes or before setContentView ran.

Common situations: Creating the insets manager in the constructor before super.onCreate; reacting to insets during very early lifecycle hooks; using the manager on a detached/recreated activity before the window is reattached.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/8e3282eb9196d350. Report an issue: GitHub.