需要帮助了解在Android中处理异常的位置

时间:2012-11-15 20:04:50

标签: java android exception exception-handling android-contentprovider

我正在尝试为我的Android应用程序提出异常处理策略(尽管这也可能适用于任何Java应用程序)。例如,我正在查看示例记事本应用程序中的delete()ContentProvider函数:

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等等,以更通用的方式(根据示例)冒泡到顶部?

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),但这让我更加困惑!

2 个答案:

答案 0 :(得分:1)

有不同的解决方法。我非常喜欢“清洁代码”一书。

你可以使用一个简单的try catch块来捕获一般异常。 在这个catch块中,您可以运行自己的书面故障方法systemOutFailure(Uri,Context,ContentResolver)。此方法检查失败并引发正确的异常。 无论如何我认为getContext永远不会为null。 您还可以更进一步,不要使用失败方法,而是使用自己的失败类来处理异常并抛出正确的异常。

抛出的问题是你必须“加强它”所以它不是很好的OO设计 - 如果你必须使用另一个异常进行更改或扩展抛出是非常静态的。

答案 1 :(得分:1)

处理异常的想法是显示错误发生的明确原因,并可能根据错误执行某些操作。所以,请考虑:

  1. 定义从Java异常派生的自己的异常类

  2. 将您的代码放在try / catch块中。当您捕获异常时,使用跟踪记录它,然后抛出您自己的异常,并附上清晰的解释。

  3. 在某些时候,您会捕获自己的异常,提取信息和 如果您提供Web服务

  4. ,则在屏幕上显示信息或发送回程序用户

    代码示例:

    public class MyException extends Exception {
    
    public static final String MYSeparator = "!@#!";
    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);
    }
    

    }