从SD卡检索图像时无法恢复活动

12

我的Activity包含以下代码,用于获取SD卡上的所有图片:

String[] projection = {MediaStore.Images.Media._ID,
                       MediaStore.Images.Media.DATA,
                       MediaStore.Images.ImageColumns.DATA};  
Cursor cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                             projection, null, null,
                             MediaStore.Images.Media._ID); 
int count = cursor.getCount();
int image_path_index = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
int i;
for(i = 0; i < count; i++) {
    cursor.moveToPosition(i);
    String p = cursor.getString(image_path_index);
    fd.addToPhonePhoto(p);
}
cursor.close();

Activity在恢复时发生了以下错误:

  

03-14 14:06:48.380:E/AndroidRuntime(20793):java.lang.RuntimeException:无法恢复活动{}:java.lang.RuntimeException:无法恢复活动{}:android.database.StaleDataException:尝试访问已关闭的游标。

这只会发生在Android 4.0上。如果在Android 2.x或3.x上,它可以正常工作。但是如果我更改系统设置,在“开发人员选项”中选择“不保留活动”选项,则错误不会显示。

我想修改我的代码以避免更改系统设置而出现此错误。我该怎么做?

3个回答

41
我认为这是由于调用了managedQuery方法并关闭了游标所致。根据managedQuery()方法的文档:

警告:不要调用使用此方法获取的游标的close()方法,因为该活动将在适当的时候代替您执行此操作。但是,如果您从托管查询中调用stopManagingCursor(Cursor)方法,则系统不会自动关闭游标,在这种情况下,您必须调用close()方法。

让Android系统处理游标,不要调用cursor.close();方法。

注意:managedQuery方法已被弃用,应避免使用,应改用实现CursorLoaders。有关CursorLoaders的更多信息,请参见developer.android.com


你的答案是正确的。但我的另一个活动也有相同的错误。代码如下:http://stackoverflow.com/questions/9426170/why-the-cusor-null 。如果没有调用cursor.close(),在运行几个循环时,游标将变为空。如何避免这种情况? - brian
@brian 也许你其他问题的原因是你所执行的操作过于庞大。你针对两列执行了完整的MediaStore.Images.Media查询,然后又进行了几百甚至一千多个managedQuery来获取缩略图(如果你想要缩略图,难道不应该查询MediaStore.Images.Thumbnails内容提供者吗?)。此外,你说游标有时为空,但在游标上调用close会不会抛出NullPointerException呢? - user
例如,我有2000张照片。从1到1000的for循环可以工作,但超过1000会得到null。如果使用NullPointerException可能会导致几张照片无法打开。 - brian
@brian 我不知道为什么会发生这种情况。也许你可以尝试新的方法来避免这个问题。 - user
好的,减少光标调用似乎是唯一的方法。无论如何,谢谢。 - brian

1

在您的代码中删除 cursor.close();,它一定能正常工作。


1

函数managedQuery()已经被弃用。

请使用getContentResolver().query()。

参数相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接