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

如何在Xamarin.Android的try-catch块中捕获所有异常?解决未捕获崩溃问题

解决Xamarin.Android中未捕获的JsonReaderException问题

我完全理解你的困惑——明明JsonReaderException继承自Exception,却没被最后一个catch块捕获,还导致应用反复崩溃,这确实反常。咱们一步步来排查和解决这个问题:

首先排查局部try-catch失效的原因

最常见的问题是异步操作没有正确使用await。如果你的Refit API调用是异步方法,但你没加await,异常会在后台线程抛出,根本不会进入当前的try-catch块。比如:

❌ 错误写法(未使用await):

try {
  _apiService.GetDataAsync(); // 没有await,异常会直接"逃逸"出当前块
} catch(Exception e) {
  // 永远不会走到这里
}

✅ 正确写法(必须await异步调用):

try {
  var response = await _apiService.GetDataAsync(); // 加上await,异常才会被捕获到当前块
} catch(System.OperationCanceledException e) {
  // 用户取消查询,显示重试选项
} catch(ApiException apiException) {
  // 发生API异常,向用户显示错误信息及重试选项
} catch(Exception e) {
  // 现在JsonReaderException会被这里正常捕获
}

如果已经正确使用了await,那可能是异常从Xamarin的Java交互层回传时的特殊情况,这时候全局异常处理就能派上用场。

添加全局未捕获异常处理器兜底

Xamarin.Android提供了几个全局异常钩子,可以捕获所有漏网的未处理异常,避免应用反复崩溃。你可以在MainActivity的OnCreate方法里添加以下代码:

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    // 捕获AppDomain层面的未处理异常
    AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
    {
        var exception = e.ExceptionObject as Exception;
        Log.Error("GlobalCrash", $"AppDomain异常: {exception?.Message}", exception);
        HandleGlobalException(exception);
    };

    // 捕获Android环境的未处理异常(包括Java层回传的异常)
    Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += (sender, e) =>
    {
        var exception = e.Exception;
        Log.Error("GlobalCrash", $"Android环境异常: {exception?.Message}", exception);
        HandleGlobalException(exception);
        e.Handled = true; // 标记为已处理,阻止系统强制崩溃
    };

    // 捕获未被观察到的Task异常(比如忘记await的异步操作)
    TaskScheduler.UnobservedTaskException += (sender, e) =>
    {
        var exception = e.Exception;
        Log.Error("GlobalCrash", $"未观察到的Task异常: {exception?.Message}", exception);
        HandleGlobalException(exception);
        e.SetObserved(); // 标记为已观察,避免后续触发崩溃
    };

    // 其他初始化代码...
}

private void HandleGlobalException(Exception exception)
{
    // 切换到UI线程显示用户提示
    RunOnUiThread(() =>
    {
        new AlertDialog.Builder(this)
            .SetTitle("应用出错")
            .SetMessage($"抱歉,应用遇到了未预期的问题:{exception?.Message}")
            .SetPositiveButton("确定", (dialog, args) => dialog.Dismiss())
            .Show();
    });
}

额外检查点

  • 确认Refit的自动解析逻辑:如果Refit已经帮你完成了JSON解析,那JsonReaderException是在Refit内部抛出的,但只要你await了调用,异常应该会正常传递到你的try-catch块。
  • 检查嵌套异步操作:如果try块内部还有其他未await的异步方法,也可能导致异常逃逸,需要确保所有异步操作都正确使用await。

通过以上步骤,既可以修复局部try-catch的问题,又能通过全局处理器兜底所有未捕获的异常,彻底解决应用反复崩溃的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:56:41