0

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

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

崩溃发生在循环中的线路上。在我看来,这可能发生的唯一方法是:

  1. cursor.getCount()正在返回不正确的计数。
  2. cursor在此循环执行时更改,但我认为这是不可能的,因为cursor它是一个局部变量。也许底层的某些东西cursor发生了我不知道的变化。
  3. mIds已经改变。这应该是不可能的,因为我们在 UI 线程上运行,并且这是唯一为该变量分配新值的地方。由于在 UI 线程上运行的性质,onPostExecute这段代码不可能同时在其他地方运行,对吧?

我错过了什么吗?

4

3 回答 3

1

试试这个:

int i = 0;
mIds = new long[cursor.getCount()];
while (cursor.moveToNext()) {
    mIds[i] = cursor.getLong(COLUMN_ID);
    i++;
}
于 2011-11-14T20:23:28.037 回答
1

如果没有看到完整的代码,很难看出该循环有什么问题,但我从文档中注意到:

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

于 2011-11-14T20:26:01.730 回答
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;

这是我的方法的备份:
Android Cursor.moveToNext() 文档是否正确?
finally 总是在 Java 中执行吗?

于 2011-11-14T20:39:31.283 回答