,我有时在我logcat中得到这个错误CursorWindow逐行读取0,列0。无法从其中有0行,64列
无法从0行64列的CursorWindow读取0行0列。
首先,有点背景故事的。我有一个应用程序可以在我们公司的许多设备上运行。主要是,它目前运行在约20台Samsung Note 8设备,2台Samsung Note 10.1设备和其他几台设备上。到目前为止,这个问题只发生在Note 8设备中的两个上。在所有其他设备上,它似乎工作得很好。
应用程序的工作原理是,用户使用应用程序来收集信息,文字,照片,签名等等......而这一切,然后存储/插入SQLite数据库作为意见表中的一行。提交表格有64列以满足收集的每个字段。有一个始终运行的同步方法(它是一个AsyncTask,它是在可运行线程内部执行的,所以即使应用程序已关闭,它仍会同步后台中的数据,除非您将其从关闭android任务管理器),它将数据同步到远程服务器,并且每10秒检查一次是否需要同步,例如,如果插入了新的提交,它将开始同步该提交。当提交完成与服务器同步并接收到成功响应时,它将从设备的数据库中删除。到目前为止,它一直在努力工作,成功地同步了成千上万的提交内容等等。但是,每隔一段时间,我会从一个或两个特定的Note 8平板电脑中得到这一个错误,以便重现此问题。我曾多次尝试重新创建该错误,但在测试它时它总能正常工作,并且我尝试了各种类型的场景来测试它。
我的代码是成千上万行的,所以我会尽量保持尽可能相关。首先,这里是可运行的相关代码:
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%工作。
另外,我将张贴在那里我居然穿越同步方法的内部数据库中的一部分:
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);
}
这对所有其他平板电脑和设备都适用。他们都从游戏存储区自动更新并继续按照他们的要求工作。但是,为什么logcat多次输出这些行?
难道这是问题的一部分,为什么我得到了这篇文章开头提到的错误?
任何可能的见解将很乐意欣赏。我一直拉着我的头发好几周,在我的代码中找不到任何错误。
更新1:
我刚才看到这样的警告:
08:30:58.710 16745#16745 WARN CursorWindow窗口已满:请求的分配307333个字节,自由空间249426个字节,窗口大小2097152字节
我想这可能是我的问题的根源。关于如何有效解决这个问题的任何想法?
更新2:
我认为一个解决办法可能是限制我从游标中获取列。例如,所有的小文本值/列。然后,然后为每个我知道占用太多空间的列创建一个新的查询。你认为这是一个解决方案吗?任何人 ?
更新3:
这可能会实现,我想最初的一个循环之后,我会做不同的游标的大油田。像这样的东西(我只是写了一些伪代码):
Cursor c = db.rawQuery("SELECT Column1, Column2 .... FROM table " + ... , ...);
解决方法:
看到我的解决方案! https://stackoverflow.com/a/26797130/1518916
“这是一个在可运行线程内部执行的AsyncTask,因此即使应用程序已关闭,它仍然会同步后台数据,除非您从Android任务管理器中将其关闭。”我不认为您的线程/ async如果您的应用程序关闭,它仍会继续运行。考虑改用SERVICE。如果活动被破坏,线程和异步将被关闭。 – 2014-11-05 11:03:32
@BlazeTama我同意你的意见。 – 2014-11-05 11:10:59
同时检查那些Note 8平板电脑的平台版本。 – vovahost 2014-11-05 11:13:53