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

如何在MauiApp创建前显示异常提示弹窗?

MAUI Android 启动前服务加载异常的提示方案

问题场景

在Android平台的MAUI项目中,我会先创建服务并加载数据,再将其注入到MauiApp中:

var myService=new();   
myService.LoadData();// 此处可能抛出异常
var builder = MauiApp.CreateBuilder();
builder.Services.AddSingleton(myService);

部分服务加载数据时会抛出异常,当前异常会直接导致应用关闭且无任何提示信息。DisplayAlert仅能在Page中使用,但Page要等到App启动后才会创建。

在Xamarin中,我使用Android.App.AlertDialog.Builder结合Android.App.Application.Context可以正常显示异常弹窗,但在MAUI中除了Toast消息外,其他方式都会抛出如下异常:

Android.Views.WindowManagerBadTokenException: 'Unable to add window -- token null is not valid; is your activity running?'

App启动前Platform.CurrentActivity为null,想请教如何获取启动页上下文显示异常,或者有没有其他方式在应用启动前显示异常信息?


解决方案

方案1:捕获异常暂存,待Activity就绪后显示弹窗

核心思路是先捕获启动阶段的异常,暂存异常信息,等MainActivity初始化完成后再弹出提示框。

步骤1:在Program.cs中捕获异常并暂存

修改Program.cs的启动逻辑,捕获服务加载时的异常,同时保证应用能正常启动到Activity阶段:

using Microsoft.Maui;
using Microsoft.Maui.Hosting;

namespace YourAppNamespace;

public static class Program
{
    // 静态变量暂存启动异常
    public static string? StartupException { get; private set; }

    [MauiProgram]
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

        try
        {
            var myService = new MyService();
            myService.LoadData();
            builder.Services.AddSingleton(myService);
        }
        catch (Exception ex)
        {
            // 捕获异常并暂存
            StartupException = ex.ToString();
            // 添加空服务实例避免依赖注入报错
            builder.Services.AddSingleton<MyService>(new MyService());
        }

        return builder.Build();
    }
}

步骤2:在MainActivity中处理异常弹窗

打开Platforms/Android/MainActivity.cs,重写OnCreate方法,在Activity就绪后检查并显示异常弹窗:

using Android.App;
using Android.Content.PM;
using Android.OS;
using AndroidX.AppCompat.App;

namespace YourAppNamespace;

[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
    protected override void OnCreate(Bundle? savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        if (!string.IsNullOrEmpty(Program.StartupException))
        {
            new AlertDialog.Builder(this)
                .SetTitle("启动失败")
                .SetMessage(Program.StartupException)
                .SetPositiveButton("退出", (sender, args) => Finish())
                .SetCancelable(false)
                .Show();
        }
    }
}

方案2:延迟服务数据加载到App启动后

如果允许调整服务初始化时机,可以将数据加载逻辑延迟到App启动完成后,此时已经可以使用DisplayAlert:

修改服务类,添加延迟加载逻辑

public class MyService
{
    public Exception? LoadException { get; private set; }
    public bool IsDataLoaded { get; private set; }

    public void LoadData()
    {
        try
        {
            // 原有的数据加载逻辑
            // ...
            IsDataLoaded = true;
        }
        catch (Exception ex)
        {
            LoadException = ex;
            IsDataLoaded = false;
        }
    }
}

在Program.cs中仅注册服务,不立即加载数据

[MauiProgram]
public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
        });

    // 仅注册服务实例,不调用LoadData
    builder.Services.AddSingleton<MyService>();

    return builder.Build();
}

在App.xaml.cs的OnStart中加载数据并处理异常

using Microsoft.Maui.Controls;

namespace YourAppNamespace;

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        MainPage = new MainPage();
    }

    protected override void OnStart()
    {
        base.OnStart();

        var myService = Services.GetRequiredService<MyService>();
        myService.LoadData();

        if (myService.LoadException != null)
        {
            MainPage.DisplayAlert("启动错误", myService.LoadException.Message, "确定");
            // 可选:显示错误后退出应用
            // Process.GetCurrentProcess().Kill();
        }
    }
}

方案3:使用Toast临时提示(简易方案)

如果不需要复杂的弹窗,仅需要简单提示,可以直接在捕获异常时调用Android的Toast:

catch (Exception ex)
{
    // 仅在Android平台显示Toast
#if ANDROID
    Android.Widget.Toast.MakeText(Android.App.Application.Context, $"启动错误:{ex.Message}", Android.Widget.ToastLength.Long).Show();
#endif
    // 后续逻辑...
}

注意事项

  • MAUI启动初期,Platform.CurrentActivity为null,此时无法创建依赖Activity上下文的弹窗(如AlertDialog),必须等Activity的OnCreate方法执行完成后才能操作。
  • 方案1的优势是可以在服务加载失败后仍让应用启动到Activity阶段,给用户明确的错误提示;方案2则更符合MAUI的生命周期规范,避免在启动阶段阻塞应用。

内容的提问来源于stack exchange,提问作者Виталий Соколов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:45:40