如何在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
相关产品推荐
相关产品推荐

