2012-05-09 27 views
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命令错误?有没有什么模式可以做到这一点?

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

回答

1

首先,不抓住这样的所有异常,就会变得很难知道什么地方出了错,并通知到底什么是错的用户。相反,做这样的事情:

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

你看,我们就在结束拍摄Exception,排序的捕获所有类型的事情,以确保我们没有错过什么。

在模型方面,我做的事情是这样的,以确保所有的数据层对象抛出自己的异常到表现层(活动),这样的活动可以对付它。在表示层,你可以选择如何向用户显示错误:通常在一个很好的,内容丰富的错误信息。但这并不总是如此。例如如果你是填充你的模型,并触及空指针,因为没有从数据库中返回,然后赶上在数据层的问题,只是不填充模型。然后,当您的表示层展示模型时,不会有任何内容,这就是表示层可以决定如何将其传达给用户的点。

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

0

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

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

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")或您自己的日志记录基础结构)。

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

+0

谢谢您的回答。我有一个特定的问题,我不知道如何处理:我连接到Web服务,检索一些数据,然后我将本地存储。如果这些数据被破坏,将会导致异常。这不是一个软件问题,我该如何处理?谢谢。 – VansFannel

+0

如果数据可能被破坏(=您希望错误不是由错误代码引起的),那么请确保捕获适当的异常(并非全部)并找到处理该情况的方法。例如。检查你检索的数据是否有效,以防万一它没有重试(并且可能会阻止你以这种方式得到的异常)。如果自动错误处理是不可能的,那么通知用户它可以在以后再次尝试,如果这是可能的话。让它崩溃的方法只适用于你应该修复的错误代码,而不是你的代码必须处理的网络超时/传输错误等。 – zapl