AvaloniaUI/Avalonia · critical · InvalidOperationException
Application.Context.MainLooper was not expected to be null.
Error message
Application.Context.MainLooper was not expected to be null.
What it means
AndroidDispatcherImpl binds to the process main Looper to dispatch UI work. In its constructor it requires App.Context.MainLooper to be non-null. A null MainLooper means the Android Application context has no main message loop available — i.e. the host process is not a normal Android app (no UI thread loop), or the context is the wrong kind.
Source
Thrown at src/Android/Avalonia.Android/AndroidDispatcherImpl.cs:30
{
internal sealed class AndroidDispatcherImpl : IDispatcherImplWithExplicitBackgroundProcessing,
IDispatcherImplWithPendingInput
{
[ThreadStatic] private static bool? s_isUIThread;
private readonly Looper _mainLooper;
private readonly Handler _handler;
private readonly Runnable _signaler;
private readonly Runnable _timerSignaler;
private readonly Runnable _wakeupSignaler;
private readonly MessageQueue _queue;
private int _signaled;
private bool _backgroundProcessingRequested;
public AndroidDispatcherImpl()
{
_mainLooper = App.Context.MainLooper ??
throw new InvalidOperationException(
"Application.Context.MainLooper was not expected to be null.");
if (!CurrentThreadIsLoopThread)
throw new InvalidOperationException("This class should be instanciated from the UI thread");
_handler = new Handler(_mainLooper);
_signaler = new Runnable(OnSignaled);
_timerSignaler = new Runnable(OnTimer);
_wakeupSignaler = new Runnable(() => { });
_queue = Looper.MyQueue();
Looper.MyQueue().AddIdleHandler(new IdleHandler(this));
CanQueryPendingInput = OperatingSystem.IsAndroidVersionAtLeast(23);
}
public event Action? Timer;
private void OnTimer() => Timer?.Invoke();
public event Action? Signaled;
private void OnSignaled()
{View on GitHub (pinned to 11c5427268)
Solutions
- Ensure AndroidDispatcherImpl is created on the main UI thread of a real Android app with Looper.MainLooper prepared (AvaloniaMainActivity lifecycle).
- If in a test/instrumentation context, prepare Looper.MainLooper before instantiating the dispatcher.
- Avoid initializing the Avalonia Android platform on background/service processes.
- Bind AvaloniaAndroid only from the main process and after Application.Context is set.
Example fix
// before
_mainLooper = App.Context.MainLooper ??
throw new InvalidOperationException("Application.Context.MainLooper was not expected to be null.");
// after (guard with actionable guidance)
_mainLooper = App.Context.MainLooper ??
throw new InvalidOperationException(
"Application.Context.MainLooper is null. Initialize the Avalonia Android platform on the UI thread of the main app process (Looper.MainLooper must be prepared)."); Defensive patterns
Strategy: validation
Validate before calling
// create the dispatcher only when a main looper exists if (App.Context.MainLooper is null) return; // not a UI-capable process
Type guard
static bool HasMainLooper() => App.Context.MainLooper is not null;
Try / catch
try { _dispatcher = new AndroidDispatcherImpl(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("MainLooper"))
{ /* not a UI process; cannot run Avalonia here */ } Prevention
- Initialize the Avalonia Android platform only on the main app process.
- Ensure Looper.MainLooper is prepared before constructing the dispatcher.
- Avoid background/service-process initialization.
When it happens
Trigger: Constructing AndroidDispatcherImpl when Application.Context (or the bound Android platform) was initialized outside a real Android app process, or before the main Looper is prepared. Also when running in an instrumentation/test context whose MainLooper is not yet available.
Common situations: Running Avalonia.Android under a non-UI host (background service, headless test runner, instrumentation without Looper.MainLooper); binding Avalonia from a context that is not the main application; multi-process apps where the dispatcher is created on a worker process.
Related errors
- This class should be instanciated from the UI thread
- Avalonia Application was not initialized. Make sure you have
- Unknown error: AvaloniaView initialization has failed.
- Activity.Window must be set.
- The control isn't currently attached to a toplevel
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/c5cc5e092e17f842.
Report an issue: GitHub.