我有时在我的logcat中得到这个错误。
无法从具有0行,64列的CursorWindow读取第0行第0列。
首先,有点背景故事。 我有一个在我们组织中的许多设备上运行的应用程序。 它主要运行在大约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会多次输出这些行?
这可能是问题的一部分,为什么我收到这篇文章开头提到的错误?
任何可能的见解都会很高兴。 我已经把头发拉了几个星期,在我的代码中找不到任何错误。
更新1:
我刚看到这个警告:
08:30:58.710 16745#16745 WARN CursorWindow窗口已满:请求分配307333字节,可用空间249426字节,窗口大小2097152字节
我猜这可能是我问题的根源。 关于如何有效解决这个问题的任何想法?
更新2:
我认为解决方案可能是限制我用光标检索的列。 例如,所有小文本值/列。 然后,为我知道占用太多空间的每个列创建一个新查询。 你认为这是一个解决方案吗? 任何人 ?
更新3:
这可能有用,我想我会在最初的一个游标被回收之后在单独的游标中做大字段。 像这样的东西(我刚写了一些伪代码):
Cursor c = db.rawQuery("SELECT Column1, Column2 .... FROM table " + ... , ...);
解: