Android中SQLite查询Blob触发CursorIndexOutOfBoundsException问题咨询
问题分析与解决办法
错误原因
你遇到的android.database.CursorIndexOutOfBoundsException本质原因是:Cursor执行查询后,默认的游标位置是-1(也就是还没有指向任何一条数据行),这时候直接调用getBlob(1)去读取数据,自然会抛出索引越界的错误。
你的代码里虽然判断了Cursor.getCount() < 1确认有数据,但没有将游标移动到有效的数据行位置,就直接尝试读取字段值,这就是问题所在。
另外还有个小细节:你的SQL查询的是ImageFile字段,游标索引是从0开始的,所以即使游标位置正确,getBlob(1)也会指向第二个字段,但你的查询只返回了一个字段,这里也会有潜在的索引越界问题,需要注意。
解决办法
修改代码,在读取Cursor数据前,先将游标移动到第一条数据行,同时修正字段索引:
SQLiteDatabase DB = this.getReadableDatabase(); ImageModel ImageModel = new ImageModel(); Cursor Cursor = DB.rawQuery("SELECT ImageFile FROM Image WHERE ID = '1'", null); if(Cursor.getCount() < 1) { System.out.println("NO DATA"); }else { System.out.println("HAVE DATA"); // 关键步骤:将游标移动到第一条数据行 Cursor.moveToFirst(); // 注意:游标字段索引从0开始,ImageFile是查询的第一个字段,所以用0 byte[] byteArray = Cursor.getBlob(0); ImageModel.setImage(BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length)); } // 最后别忘了关闭Cursor,避免资源泄漏 Cursor.close();
额外优化建议
- 操作Cursor后一定要记得调用
close()释放资源,防止内存泄漏; - 可以用
moveToFirst()的返回值来判断是否移动成功,替代getCount()的判断,代码更简洁严谨:if(Cursor.moveToFirst()) { // 读取数据逻辑 } - 避免硬编码字段索引,建议用
Cursor.getColumnIndex("ImageFile")获取字段对应的索引,这样即使SQL查询的字段顺序改变,代码也不会出错:int columnIndex = Cursor.getColumnIndex("ImageFile"); byte[] byteArray = Cursor.getBlob(columnIndex);
内容的提问来源于stack exchange,提问作者hery
相关产品推荐
相关产品推荐

