0

我想爲我的Android應用程序提供異常處理策略(儘管這也可能適用於任何Java應用程序)。例如,我在這個例子中記事本應用程序看刪除()函數的ContentProvider:需要幫助瞭解在Android中處理異常的位置

public int delete(Uri uri, String where, String[] whereArgs) { 
    SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 
    int count; 
    switch (sUriMatcher.match(uri)) { 
     case NOTES: 
      count = db.delete(NOTES_TABLE_NAME, where, whereArgs); 
      break; 

     case NOTE_ID: 
      String noteId = uri.getPathSegments().get(1); 
      count = db.delete(NOTES_TABLE_NAME, NoteColumns._ID + "=" + noteId 
        + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs); 
      break; 

     default: 
      throw new IllegalArgumentException("Unknown URI " + uri); 
    } 

    getContext().getContentResolver().notifyChange(uri, null); 
    return count; 
} 

發生什麼情況,如果Uri是空?或getContext()?或getContentresolver()?

我得出結論,ContentResolver不是捕捉異常的地方,但它應該重新拋出它們或拋出新的異常,以便應用程序可以顯示有意義的錯誤消息。

以下或類似的東西會不會是一個壞的方法(矯枉過正) - 我是否應該讓NullPointerException s等泡到頂端,以更通用的方式處理(按照示例)?

public int delete(Uri uri, String where, String[] whereArgs) 
    throws SQLiteException, IllegalArgumentException, NotifyException { 

    if (null != mOpenHelper) { 
     SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 
     if (null != db) { 
      if (null != uri) { 
       int count = 0; 
       switch (sUriMatcher.match(uri)) { 
        case NOTES: 
         count = db.delete(NOTES_TABLE_NAME, where, whereArgs); 
         break; 

        case NOTE_ID: 
         String noteId = uri.getPathSegments().get(1); 
         count = db.delete(NOTES_TABLE_NAME, NoteColumns._ID + "=" + noteId 
         + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs); 
         break; 

        default: 
         throw new IllegalArgumentException("Unknown URI " + uri); 
       } 

       if (null != getContext()) && (null != getContentResolver()) { 
        getContext().getContentResolver().notifyChange(uri, null); 
       } else { 
        throw NotifyException("Failed to notify change"); 
       } 
       return count; 
      } else { 
       throw new IllegalArgumentException("Must provide URI"); 
      } 
     } else { 
      throw new SQLiteException("Failed to get database"); 
     } 
    } else { 
     throw new SQLiteException("Invalid database helper"); 
    } 
} 

聲明:此代碼可能無法編譯!這是一個例子。

這當然更難讀!我不知道什麼是正確的平衡,需要一些幫助!

更新:我通讀了Android的推薦做法(請參閱http://source.android.com/source/code-style.html#java-language-rules),但它讓我更加困惑!

回答

1

處理異常的想法是爲了顯示發生錯誤的明確原因,並可能根據錯誤執行某些操作。所以,請考慮:

  1. 定義從Java異常

  2. 派生自己的異常類代碼放在try/catch塊。當你發現一個異常時,你用一個跟蹤記錄它,然後拋出你自己的例外,並給出清晰的解釋。

  3. 在某些時候,你趕上自己的異常,提取信息和 在屏幕上顯示的信息要麼或返回給程序的用戶,如果你提供一個Web服務

代碼示例:

public class MyException extends Exception { 

public static final String MYSeparator = "[email protected]#!"; 
public MyException() { 
    super(); 
} 

public MyException(String message) { 
    super(message); 
} 

public MyException(Throwable cause) { 
    super(cause); 
} 

public MyException(String message, Throwable cause) { 
    super(message, cause); 
} 

public MyException(String errorCode, String errorDescription, 
     Throwable cause) { 
    super(errorCode + MYSeparator + errorDescription, cause); 
} 

public MyException(String errorCode, String errorDescription) { 
    super(errorCode + MYSeparator + errorDescription); 
} 

}

1

解決這個問題的方法有很多。我非常喜歡「Clean Code」一書。

您可以使用一個簡單的try catch塊捕獲一般異常。 在此catch塊中,您可以運行自己的失敗方法systemOutFailure(Uri,Context,ContentResolver)。此方法檢查失敗並引發正確的異常。 反正我認爲getContext永遠不能爲空。 您也可以更進一步,不要使用失敗方法,而要使用自己的失敗類來處理異常並引發正確的錯誤。

拋出的問題在於你必須「提升」它所以它不是很好的OO設計 - 如果你必須進行更改或擴展與另一個異常拋出是非常靜態的。