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

Xamarin Forms Android版Release模式遇API异常崩溃求助

问题分析与解决方案

核心问题定位

你的Xamarin Forms安卓端出现异常冻结/崩溃,而iOS正常,主要集中在API异常场景,大概率是安卓端全局异常捕获不完整、异步方法调用不当、事件重复注册这几个原因导致的。

具体修复步骤

1. 补全安卓端原生异常捕获

Xamarin Forms的全局异常处理无法覆盖安卓原生层面的未捕获异常,必须在安卓项目的MainActivity中单独处理:

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    Xamarin.Essentials.Platform.Init(this, savedInstanceState);
    global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

    // 捕获安卓原生未处理异常
    AndroidEnvironment.UnhandledExceptionRaiser += (sender, e) =>
    {
        // 用Task.Run避免阻塞UI线程
        _ = Task.Run(() => YourExceptionHandlerInstance.HandleExceptionAsync(e.Exception));
        e.Handled = true; // 标记为已处理,阻止系统强制崩溃
    };

    // 捕获未观察到的Task异常
    TaskScheduler.UnobservedTaskException += (sender, e) =>
    {
        _ = Task.Run(() => YourExceptionHandlerInstance.HandleExceptionAsync(e.Exception));
        e.SetObserved();
    };

    // 捕获AppDomain层面的异常
    AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
    {
        if (e.ExceptionObject is Exception exception)
        {
            _ = Task.Run(() => YourExceptionHandlerInstance.HandleExceptionAsync(exception));
        }
    };

    LoadApplication(new App());
}

2. 修复异常处理器代码缺陷

(1)替换不准确的异常类型判断

把通过GetType().Name判断异常类型的方式,改成更可靠的is关键字,支持继承场景:

// 原代码
// if (exception.GetType().Name == nameof(UnauthorizedException))
// 替换为
if (exception is UnauthorizedException ||
    exception.Message.ToLowerInvariant().Contains("refresh token has expired") ||
    exception.Message.ToLowerInvariant().Contains("invalid refresh token"))
(2)避免重复注册网络事件

HandleNoInternetException中每次触发都注册ConnectivityChanged,会导致事件多次绑定,引发重复执行甚至内存泄漏:

private bool _isConnectivityEventBound = false;

private void HandleNoInternetException()
{
    if (Connectivity.NetworkAccess != NetworkAccess.Internet)
    {
        // 这里可以添加无网提示逻辑
    }

    if (!_isConnectivityEventBound)
    {
        Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
        _isConnectivityEventBound = true;
    }
}

private void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e)
{
    if (e.NetworkAccess == NetworkAccess.Internet)
    {
        // 恢复网络后的操作
        Connectivity.ConnectivityChanged -= Connectivity_ConnectivityChanged;
        _isConnectivityEventBound = false;
    }
}
(3)移除空catch块,保留异常日志

空catch会吞掉潜在问题,至少添加日志便于排查:

#if !DEBUG
try
{
    //await emailManager.SendFeedbackEmail(exception);
}
catch (Exception ex)
{
    Log.Error(ex, "发送异常反馈邮件失败");
}
#endif

3. 确保异步方法被正确调用

HandleExceptionAsync是异步方法,必须用await调用,避免同步调用导致UI线程死锁:

// 在API调用的catch块中
catch (Exception ex)
{
    await YourExceptionHandlerInstance.HandleExceptionAsync(ex).ConfigureAwait(false);
}

调试建议

开启安卓Logcat,查看崩溃时的原生日志,定位是否有未被捕获的JNI异常、主线程阻塞等问题,这是排查安卓端崩溃的关键。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:55:11