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设计 - 如果你必须进行更改或扩展与另一个异常抛出是非常静态的。