我有AsyncTask
查询内容提供商,并在该任务的onPostExecute()
中进行一些额外处理。我有一个非常难以重现的异常的堆栈跟踪,但我想防止这种情况或修复代码。代码如下:
int i = 0;
mIds = new long[cursor.getCount()];
while (cursor.moveToNext()) {
mIds[i++] = cursor.getLong(COLUMN_ID);
}
崩溃发生在循环线上。我看待它的方式,这可能发生的唯一方式 如果:
cursor.getCount()
返回错误的计数。cursor
已更改,但我认为不可能
因为cursor
是一个局部变量。也许cursor
背后的某些东西已经改变,我不知道。mIds
已更改。这是不可能的,因为我们正在运行
在UI线程上,这是分配该变量的唯一位置
一个新的价值。根据在UI线程上运行的onPostExecute
的性质,此代码不应该同时在其他地方运行,对吗?我错过了什么吗?
答案 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?