【发布时间】:2013-10-22 01:17:09
【问题描述】:
我正在尝试在我的 monodroid 应用程序中实现有效的异常处理,该应用程序是用 Visual Studio 的 Xamarin.Android 插件编写的。
我正在尝试处理两种类型的异常:
- 在前台 (UI) 线程
- 在后台(线程池)线程
在全局处理程序的这两种情况下,我都想:
- 记录 - (提交分析事件)
- 用户通知 -(警报)
经过一定的调查,我找到了一些答案 here、here 和 here,但除了提出了 AndroidEnvironment.UnhandledExceptionRaiser 和 AppDomain.UnhandledException 之外,没有任何答案,但并非在所有情况下都有效。
我在尝试同时使用这两个处理程序的地方创建了简短示例:
AppDomain.CurrentDomain.UnhandledException += (s,e)=>
{
System.Diagnostics.Debug.WriteLine("AppDomain.CurrentDomain.UnhandledException: {0}. IsTerminating: {1}", e.ExceptionObject, e.IsTerminating);
};
AndroidEnvironment.UnhandledExceptionRaiser += (s, e) =>
{
System.Diagnostics.Debug.WriteLine("AndroidEnvironment.UnhandledExceptionRaiser: {0}. IsTerminating: {1}", e.Exception, e.Handled);
e.Handled = true;
};
然后在单击按钮时,我添加了以下代码来引发两种类型的异常:
//foreground exception
throw new NullReferenceException("test nre from ui thread.");
//background exception
ThreadPool.QueueUserWorkItem(unused =>
{
throw new NullReferenceException("test nre from back thread.");
});
因此,我对两种类型的异常都有不同的行为:
- 前景:
- 两个处理程序都被提升了
- 无法阻止应用程序被 crashed - 它会以任何方式崩溃(e.Handled = true 只是被忽略)
- 背景:
- 仅引发第二个处理程序
- 应用不会崩溃
就我而言,我无法将每个用户操作都包含在 try-catch 中,尤其是后台任务。 我有业务登录,如果出现错误应该中断,这正是我对运行时的期望。同时我想在一个地方处理顶级异常,记录它们(基于我的业务规则)并继续执行应用程序。
如何处理异常并仍然能够使应用程序保持活动状态(防止崩溃)。
您可以在此处找到完整的代码示例: https://dl.dropboxusercontent.com/u/19503836/UnhandledException.zip
感谢您的建议。任何帮助表示赞赏。 蒂亚!
【问题讨论】:
-
这种异常处理方法的设计非常糟糕。应该在引发和预期的地方处理异常,而不是全局处理。一旦异常冒泡到全局处理程序,您就失去了所有上下文和恢复状态的所有希望。
-
感谢您的意见,但我不能同意。我确实理解并且我同意我应该在它丢失上下文之前处理异常,但我不同意在他们提出的异常处处理。成像 我有数据访问、业务逻辑和 UI,我在 UI 级别有按钮,它启动一些数据访问操作,然后由业务逻辑处理,最后结果显示在 UI 上。如果数据访问级别发生任何错误,我希望我的数据访问和业务逻辑被中断,结果显示在 UI 级别。异常被设计为在每次方法调用后不检查错误...
-
我同意我应该在我期望的地方处理这个错误 - 在 UI 级别,而不是在它引发的地方(在数据访问级别)。在我的问题中,我谈论的是在 UI 级别处理错误错误的一般方法(想象 UI 错误处理程序未能记录错误)。在这种情况下,我仍然希望我的应用程序通知用户,记录此后续错误并且让我的应用程序不崩溃(在我的情况下,未能记录错误不是关键问题)。我想要的是决定我自己是否应该在引发未经处理的异常时终止应用程序。
-
正如我之前所说,一般情况不是恢复而是记录错误并通知用户 - 但不是静默的应用程序崩溃。无声崩溃 - 这是一个糟糕的架构设计。
-
@323go 我是 Android 开发新手,所以请帮助我了解替代方案:如何处理应用程序中的意外错误?您是否将每个用户操作(按钮单击事件处理程序等)包装在 try/catch 中,或者是否有另一种方法来执行“如果所有其他方法都失败,至少向用户显示异常消息?”
标签: android exception-handling xamarin.android xamarin unhandled-exception