2012-05-09 30 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