You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI自定义Window类触发MauiContext为空致命异常求助

处理.NET MAUI自定义Window时MauiContext为null的致命异常

问题场景

自定义MyWindow继承自Window,重写OnStopped和OnResumed通过WeakReferenceMessenger发送启停消息;在App.xaml.cs中重写CreateWindow返回传入MainPage的MyWindow实例。应用从后台恢复时触发致命异常:System.InvalidOperationException: MauiContext is null。

代码示例

public class Message : ValueChangedMessage<string>
{
    public Message(string message) : base(message) 
    { 
    }
}

public class MyWindow : Window
{
    public MyWindow() : base()
    {
    }
    public MyWindow(Page page) : base(page)
    {
    }
    protected override void OnStopped()
    {
        WeakReferenceMessenger.Default.Send(new Message("Stopped"));
    }
    protected override void OnResumed()
    {
         WeakReferenceMessenger.Default.Send(new Message("Resumed"));
    }
}

// App.xaml.cs中重写的方法
protected override Window CreateWindow(IActivationState activationState)
{
    return new MyWindow(MainPage);
}

异常栈信息

Fatal Exception: android.runtime.JavaProxyThrowable:  
System.InvalidOperationException: MauiContext is null.

at Microsoft.Maui.Controls.Window.get_MauiContext()
at Microsoft.Maui.Controls.Platform.AlertManager.Subscribe(Window window)
at Microsoft.Maui.Controls.Platform.AlertManager.Subscribe()
at Microsoft.Maui.Controls.Window.<>c__DisplayClass206_0.g__OnPageHandlerChanged|0(Object sender, EventArgs e)
at Microsoft.Maui.Controls.Window.OnPageChanged(BindableObject bindable, Object oldValue, Object newValue)
at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, Boolean silent)
at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value, Boolean fromStyle, Boolean checkAccess)
at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value)
at Microsoft.Maui.Controls.Window.set_Page(Page value)
at Microsoft.Maui.Controls.Window..ctor(Page page)
at name.ViewModels.MyWindow..ctor(Page page)
at name.App.CreateWindow(IActivationState activationState)
at Microsoft.Maui.Controls.Application.Microsoft.Maui.IApplication.CreateWindow(IActivationState activationState)
at Microsoft.Maui.Platform.ApplicationExtensions.CreatePlatformWindow(Activity activity, IApplication application, Bundle savedInstanceState)
at Microsoft.Maui.MauiAppCompatActivity.OnCreate(Bundle savedInstanceState)
at name.MainActivity.OnCreate(Bundle savedInstanceState)
at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(IntPtr , IntPtr , IntPtr )
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPL_V(_JniMarshal_PPL_V , IntPtr , IntPtr , IntPtr )
   at crc64790243dcc0ae3d15.MainActivity.n_onCreate(MainActivity.java)
   at crc64790243dcc0ae3d15.MainActivity.onCreate(MainActivity.java:40)
   at android.app.Activity.performCreate(Activity.java:7994)
   at android.app.Activity.performCreate(Activity.java:7978)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1534)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3439)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3632)
   at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
   at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2067)
   at android.os.Handler.dispatchMessage(Handler.java:106)
   at android.os.Looper.loop(Looper.java:223)
   at android.app.ActivityThread.main(ActivityThread.java:7701)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

解决方案

根源分析

在Window构造函数中直接传入Page时,内部会触发PageHandlerChanged事件,此时Window的MauiContext尚未完成初始化,导致AlertManager订阅操作失败抛出异常。

方案1:延迟设置Page(推荐)

避免在构造函数中直接传入Page,改为在Window加载完成后再设置:

public class MyWindow : Window
{
    public MyWindow() : base()
    {
    }

    public MyWindow(Page page) : base()
    {
        Loaded += (sender, args) =>
        {
            if (Page == null)
                Page = page;
        };
    }

    protected override void OnStopped()
    {
        WeakReferenceMessenger.Default.Send(new Message("Stopped"));
    }

    protected override void OnResumed()
    {
        WeakReferenceMessenger.Default.Send(new Message("Resumed"));
    }
}

// App.xaml.cs中修改CreateWindow
protected override Window CreateWindow(IActivationState activationState)
{
    // 每次创建新的MainPage实例,避免复用导致的状态异常
    return new MyWindow(new MainPage());
}

方案2:通过HandlerChanged确保MauiContext可用

如果必须在构造时关联Page,可监听HandlerChanged事件,确保MauiContext初始化完成后再执行相关操作:

public class MyWindow : Window
{
    public MyWindow(Page page) : base(page)
    {
        HandlerChanged += OnWindowHandlerChanged;
    }

    private void OnWindowHandlerChanged(object sender, EventArgs e)
    {
        if (Handler != null && MauiContext != null)
        {
            // 这里可以执行依赖MauiContext的初始化操作
            HandlerChanged -= OnWindowHandlerChanged; // 移除监听避免重复触发
        }
    }

    protected override void OnStopped()
    {
        WeakReferenceMessenger.Default.Send(new Message("Stopped"));
    }

    protected override void OnResumed()
    {
        WeakReferenceMessenger.Default.Send(new Message("Resumed"));
    }
}

额外注意事项

  • 应用后台恢复时,系统会重新调用CreateWindow,不要复用App中提前初始化的MainPage静态实例,每次创建新的MainPage可以避免页面状态异常,同时减少MauiContext相关问题的触发概率。

内容的提问来源于stack exchange,提问作者devdennis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 00:31:03