如何处理数据库异常:软件设计

时间:2012-05-09 13:53:35

标签: android exception-handling software-design

我正在开发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 个答案:

答案 0 :(得分:1)

首先,不要抓住所有类似的例外情况,很难知道出了什么问题,并告知用户究竟出了什么问题。而是做这样的事情:

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

你看到我们在最后捕获Exception,类似于捕获所有类型的东西,以确保我们没有遗漏任何东西。

就您的模型而言,我这样做的方法是确保所有数据层对象将其异常抛到表示层(活动),以便活动可以处理它。在表示层,您可以选择如何向用户显示错误:通常在一个很好的,信息丰富的错误消息中。但情况可能并非总是如此。例如,如果您填充模型并点击空指针,因为数据库没有返回,那么在数据层捕获问题,只是不填充模型。然后当你的表示层去展示模型时,那里就没有任何东西,那就是你的表示层可以决定如何将它传达给用户的点。

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

答案 1 :(得分:0)

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

这实际上取决于您期望的异常类型,我看到您撤消所有异常,但您应该能够将其缩小到特定异常,您可以让调用者处理异常,然后您可以显示吐司或者在异常可以恢复的情况下帮助用户的东西。

答案 2 :(得分: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")或您自己的日志记录基础结构)。

答案 3 :(得分:0)

您可能需要查看SQLiteOpenHelper以便为您打开数据库(一次或很少)。如果您希望多个流程或应用能够访问数据,请与ContentProvider结合使用。

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

只有在某些情况下(例如文件I / O)存在您期望产生错误的代码并且您知道如何处理它们时,才能捕获异常。

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

只需将消息打印到logcat即可使用

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

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