java的cursor_java – Cursor.moveToNext错误

我偶尔会看到一个崩溃报告:

Fatal Exception: java.lang.IllegalStateException: Couldn't read row 1127, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.

at android.database.CursorWindow.nativeGetLong(CursorWindow.java)

at android.database.CursorWindow.getLong(CursorWindow.java:511)

at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)

at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220)

at android.database.AbstractCursor.moveToNext(AbstractCursor.java:245)

at android.database.CursorWrapper.moveToNext(CursorWrapper.java:166)

at com.anthonymandra.util.ImageUtils.cleanDatabase(SourceFile:381)

显然,moveToNext在循环中间失败(注意第1127行).循环删除表示无法再找到的文件的条目.

final ArrayList operations = new ArrayList<>();

try( Cursor cursor = c.getContentResolver().query(Meta.CONTENT_URI, null, null, null, null))

{

if (cursor == null)

return;

final int uriColumn = cursor.getColumnIndex(Meta.URI);

final int idColumn = cursor.getColumnIndex(BaseColumns._ID);

while (cursor.moveToNext())

{

String uriString = cursor.getString(uriColumn);

if (uriString == null) // we've got some bogus data, just remove

{

operations.add(ContentProviderOperation.newDelete(

Uri.withAppendedPath(Meta.CONTENT_URI, cursor.getString(idColumn))).build());

continue;

}

Uri uri = Uri.parse(uriString);

UsefulDocumentFile file = UsefulDocumentFile.fromUri(c, uri);

if (!file.exists())

{

operations.add(ContentProviderOperation.newDelete(Meta.CONTENT_URI)

.withSelection(getWhere(), new String[]{uriString}).build());

}

}

}

c.getContentResolver().applyBatch(Meta.AUTHORITY, operations);

知道游标如何在循环中失败吗?

解决方法:

您似乎正在进行一个相当大的查询:至少1127行,以及所有可能的列(尽管您只使用其中两个).并且,在使用该Cursor期间,您正在将磁盘I / O和/或IPC返回到ContentProvider,假设UsefulDocumentFile与Android的DocumentFile相关.

正如Prakash所说,你得到的光标可能只包含一部分信息.一旦您尝试超越该点,Cursor就需要返回数据源并获得下一个结果窗口.如果在进行此项工作时数据发生了重大变化(例如,现在少于1127行),我可以看到您遇到此类问题.

我建议你:

>限制返回到所需子集的列,以及

>在循环期间避免I / O(例如,旋转Cursor以构建ArrayList< Pair>或其他东西,关闭Cursor,然后迭代列表)

标签:java,android,sqlite,android-contentprovider,android-cursor

来源: https://codeday.me/bug/20190611/1218697.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package com.music.zhangdaosen; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.provider.MediaStore; import android.util.Log; import android.widget.ArrayAdapter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class SongHelper { public static List<Song>musicList = new ArrayList<>(); // static List<Song>musicList; public static List<Song> getLocalMusic(Context context){ Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; ContentResolver resolver = context.getContentResolver(); Cursor cursor = resolver.query(uri,null,null,null,null); if(cursor !=null){ Song song; while (cursor.moveToNext()){ song =new Song(); int index = cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME); song.name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)); song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)); song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)); Log.d("SongHelper--keyar","get"+song.name+" "+song.duration); musicList.add(song); SimpleDateFormat sdf = new SimpleDateFormat("mm:ss"); String time = sdf.format(new Date(song.duration)); } Log.d("SongHelper--keyar","get musicList"+ musicList.size()); } cursor.close(); return musicList; } public static String changeTime(int duration){ int min = duration/1000/60; int sec = duration/1000%60; if(sec<10){ return min+":0"+sec; } return min+":"+sec; } }
最新发布
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值