难以理解抛出此ArrayIndexOutOfBounds异常的方式

时间:2011-11-14 20:19:17

标签: android android-cursor

我有AsyncTask查询内容提供商,并在该任务的onPostExecute()中进行一些额外处理。我有一个非常难以重现的异常的堆栈跟踪,但我想防止这种情况或修复代码。代码如下:

int i = 0;
mIds = new long[cursor.getCount()];
while (cursor.moveToNext()) {
    mIds[i++] = cursor.getLong(COLUMN_ID);
}

崩溃发生在循环线上。我看待它的方式,这可能发生的唯一方式 如果:

  1. cursor.getCount()返回错误的计数。
  2. 执行此循环时,
  3. cursor已更改,但我认为不可能 因为cursor是一个局部变量。也许cursor背后的某些东西已经改变,我不知道。
  4. mIds已更改。这是不可能的,因为我们正在运行 在UI线程上,这是分配该变量的唯一位置 一个新的价值。根据在UI线程上运行的onPostExecute的性质,此代码不应该同时在其他地方运行,对吗?
  5. 我错过了什么吗?

3 个答案:

答案 0 :(得分:1)

试试这个:

int i = 0;
mIds = new long[cursor.getCount()];
while (cursor.moveToNext()) {
    mIds[i] = cursor.getLong(COLUMN_ID);
    i++;
}

答案 1 :(得分:1)

在没有看到完整代码的情况下很难看出该循环有什么问题,但我从docs注意到:

  

不需要同步Cursor实现,因此使用Cursor时,使用来自多个线程的Cursor的代码应该执行自己的同步。

答案 2 :(得分:0)

根据我的经验,我总是这样做。似乎可以避免大多数问题。

Cursor cursor = null;

try
{
    cursor = getDb().rawQuery(query, params); // your call to database here...
    if (cursor == null || cursor.getCount() == 0)
        return false;

    cursor.moveToFirst();

    mIds = new long[cursor.getCount()];
    int i = 0;

    do
    {
        mIds[i] = cursor.getLong(COLUMN_ID);
        i++;
    } while (cursor.moveToNext())
} catch(Exception e) {
    // Do error handling
    return false;
}
finally
{
    closeCursor(cursor);
    cursor = null;
}

return true;

这是我的方法的备份:
Is Android Cursor.moveToNext() Documentation Correct?
Does finally always execute in Java?