我有时会在我的logcat中收到此错误。
无法从CursorWindow读取第0行第0列,其中包含0行,64列。
首先,有点背后的故事。我有一个在我们组织中的许多设备上运行的应用程序。它主要运行在大约20个三星Note 8设备,2个三星Note 10.1设备和其他几个。到目前为止,问题仅发生在Note 8设备中的2个。在所有其他设备上它似乎工作正常。
应用程序的工作原理是用户使用该应用程序收集信息,文本,照片,签名等......然后将所有这些内容作为提交表中的一行存储/插入SQLite数据库。提交表有64列,以满足每个收集的字段。有一个始终在运行的同步方法(在可运行的线程中执行 AsyncTask ,所以即使应用程序关闭,它仍然会同步数据在后台,除非你从android任务管理器中滑动关闭它,它将数据同步到远程服务器,如果需要同步则每10秒检查一次,例如,如果插入了新的提交,它将开始同步提交。提交完成后,与服务器同步并收到成功响应,然后将其从设备的数据库中删除。到目前为止它已经工作得很好,数千个提交已成功同步等等。但是,我不时地从一两个特定的Note 8平板电脑中得到这一个错误,可以重现这个问题。我已经多次尝试重新创建错误,但是当我测试它并且我已经尝试了各种类型的场景来测试它时它总是有效。
我的代码是数千行,所以我会尽量保持相关性。首先,这是runnable的相关代码:
public Runnable myRunnable = new Runnable()
{
@Override
public void run()
{
count ++;
if(count >= 10)
{
android.util.Log.w(" SYNC ", "---------------");
android.util.Log.w(" SYNC ", "Checking if sync method is busy");
if(!syncBusy)
{
android.util.Log.w(" SYNC ", "Sync method OPEN");
doSync();//This will start doing sync.
count = 0;
}
else
{
android.util.Log.w(" SYNC ", "Sync method BUSY, will try again in 10 seconds");
android.util.Log.w(" SYNC ", "---------------");
}
}
if(count == 1 && !syncBusy)
{
checkSubmissionsLefttoSync();
}
mHandler.postDelayed(myRunnable, 1000);
}
};
然后,doSync()方法是我上传的地方,也是我收到错误的地方。它长达数千行,所以我不想在这里发布代码。我可以说的是,除了产生上述错误的一两个例外情况外,它对所有设备都有100%的效果。
另外,我将在sync方法中发布实际遍历数据库的部分:
databaseHelper = new Handler_Database(this);
Cursor cursor2 = databaseHelper.getAllUnsyncedSubmissions();
if(cursor2.getCount() > 0)
{
if(cursor2.moveToFirst())
{
do
{
try
{
//doing lookups here and populating sync arrays
}
catch (IllegalStateException e)
{
//Do Nothing
}
catch (NullPointerException e)
{
//Do Nothing
}
}
while(cursor2.moveToNext());
}
else
{
}
}
else
{
}
cursor2.close();
databaseHelper.close();
我注意到了别的东西,我不确定它是否有问题,但是,当我运行应用程序时,logcat会输出以下行约6或7次:
12:48:11.115 7416#7416 DEBUG SQLiteOpenHelper DB版本:60
我在应用启动时会收到自己的警告消息,而这些消息只显示一次。但是,db版本和其他信息正在多次写入logcat。这是一个问题吗?这是否意味着我的数据库存在某种错误,它会创建多个实例?
所有应用都使用 Playstore 中签名的apk进行更新。我的数据库onUpgrade方法如下所示:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_SUBMISSIONS);
// Create tables again
onCreate(db);
}
这适用于所有其他平板电脑和设备。它们都从Playstore自动更新,并继续按预期工作。但是,为什么logcat会多次输出这些行?
这可能是问题的一部分,为什么我会收到本文开头提到的错误?
任何可能的见解都会很高兴。我已经把头发拉了几个星期,在我的代码中找不到任何错误。
我刚看到这个警告:
08:30:58.710 16745#16745 WARN CursorWindow窗口已满:请求分配307333字节,可用空间249426字节,窗口大小2097152字节
我想这可能是我问题的根源。关于如何有效解决这个问题的任何想法?
我认为解决方案可能是限制我使用游标检索的列。例如,所有小文本值/列。然后,为我知道占用太多空间的每个列创建一个新查询。你认为这是一个解决方案吗?任何人 ?
这可能有用,我想我会在最初的一个游标被回收后用单独的游标做大字段。像这样的东西(我刚写了一些伪代码):
Cursor c = db.rawQuery("SELECT Column1, Column2 .... FROM table " + ... , ...);
在这里查看我的解决方案! https://stackoverflow.com/a/26797130/1518916
答案 0 :(得分:6)
我完成了我的解决方案,现在工作正常。基本上,底线是在android上的sqlite数据库中存储大数据并不理想。处理图像时,只需存储URI并将图像保留在设备上。但是,如果必须,那么我建议不要将所有图像数据加载到同一个光标中,将它们拆分并进行多次查询。
答案 1 :(得分:3)
当您的图片尺寸较大时会发生此错误。存储图像的URL或在存储之前压缩图像。