0

我正在开发 Android 3.1 及更高版本的应用程序,但这个问题并不特定于特定环境。

我有三层:活动(表示)、模型(表示数据库表的对象)和数据(访问 SQLite 数据库的类)。

我所有的数据库方法都是这样的:

public void insertUserAnswers(ArrayList<UserAnswer> answers)
{
    try
    {
        if ((db == null) || (!db.isOpen()))
            this.open();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    finally
    {
        this.close();
    }
}

如您所见,我捕获了每个异常并且我没有通知任何人,因为(这是我的问题)我不知道该怎么做。

如何通知它是 sql 命令的错误?有什么模式可以做到这一点吗?

我想我可以返回一个值来指示或不缓存异常。

4

4 回答 4

1

首先,不要像这样捕获所有异常,很难知道出了什么问题并通知用户究竟出了什么问题。而是做这样的事情:

try {
    operationThatThrowsMultipleExceptions();
}
catch (ExceptionTypeOne e){
    // do something here
}
catch (ExceptionTypeTwo e){
    // do something here
}
catch (Exception e){
    // do something here
}

你会看到我们Exception在最后捕捉到了,有点像捕捉所有类型的东西,以确保我们没有错过任何东西。

就您的模型而言,我这样做的方式是确保所有数据层对象都将其异常抛出到表示层(活动),以便活动可以处理它。在表示层,您可以选择如何向用户展示错误:通常以漂亮、信息丰富的错误消息的形式。不过,情况可能并非总是如此。例如,如果您正在填充模型并点击空指针,因为数据库没有返回,那么在数据层发现问题并且不填充模型。然后,当您的表示层开始展示模型时,那里不会有任何东西,这就是您的表示层可以决定如何将其传达给用户的点。

总结:除非真的有必要,否则不要在数据层捕获异常。

于 2012-05-09T14:19:32.867 回答
0

对,对不起,我没有正确阅读你的问题,所以改变了我的答案。

这实际上取决于您期望的异常类型,我看到您取消了所有异常,但是您应该能够将其范围缩小到特定异常,您可以让调用者处理异常,然后您可以显示祝酒词或其他内容如果异常是可恢复的,将帮助用户。

于 2012-05-09T14:02:52.953 回答
0

一般来说,如果您打算对错误采取行动,或允许其他对象对其采取行动(优雅降级左右),那么返回合适的返回值似乎是正确的。然后该insertUserAnswers方法可以返回一个数值,例如:

0: "Success"
1: "IO error (file system not accessible or so)"
2: "SQL error (invalid insert query, invalid arguments, ...)"

这可能需要您捕获比基础更具体的异常Exception,以便确定出了什么问题。

另外:作为用户,我不关心有关错误的技术细节。我什至不确定我是否对是否有错误感兴趣。因此,如果您问我,显示错误对话框不一定是“对错误采取行动”。如果这是您打算做的唯一事情(显示错误对话框),那么我建议您不要打扰返回值并完全跳过错误通知。

您应该始终以某种方式记录错误(如果您愿意,可以通过Log.e("MyTag", "My log message")或您自己的日志基础设施)。

于 2012-05-09T14:16:35.863 回答
0

您可能想看看为SQLiteOpenHelper您打开数据库(一次或很少)。ContentProvider如果您希望多个进程或应用程序能够访问数据,请结合使用。

然后确保您的代码不会产生错误(在 SQLite 级别等),如果您忘记了某些内容,只需让应用程序崩溃 - 这是知道您做错了什么的最安全方法,还允许您通过 Play/Market 报告错误。

仅当您希望在某些情况下(如文件 I/O)产生错误的代码并且您知道如何处理它们时,捕获异常才是好的。

捕获所有内容只会隐藏您的错误并使其难以检测(用户必须不断监视日志消息左右)。如果您的应用程序没有崩溃但也不可用,因为它需要数据库才能运行,您可能会让用户感到困惑,而不仅仅是让它崩溃。

并简单地将消息打印到 logcat 使用

catch (Exception e) {
    // either 
    Log.w("TAG", e);
    // or
    Log.e("TAG", "some message", e);
}

这将打印带有标签/日志级别的消息,您可以选择而不是使用W/System.err

于 2012-05-09T14:23:43.223 回答