我正在开发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命令出错?有什么模式可以做到吗?
我想我可以返回一个值来表示是否缓存异常。
答案 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