异步任务期间的游标异常
Cursor Exception during Async Task
我是 运行 一个后台任务,它会下载一个 JSON 文件,解析它,然后将它添加到 SQLite 数据库的内容中。
我在运行时遇到了一些错误。
Caused by: android.database.CursorWindowAllocationException: Cursor
window allocation of 2048 kb failed. # Open Cursors=728 (# cursors
opened by this proc=728)
E/CursorWindow: Could not allocate CursorWindow
'/data/data/com.mycompany.inventory/databases/dbInventory.sql' of size
2097152 due to error -12.
JSON 中有大约 1500 个项目。
这是我的异步任务调用的方法:
public void addModelsToDB(JSONObject dict){
String insertQuery = "";
String deleteQuery = "DROP TABLE IF EXISTS 'tblModels'";
String createQuery = "CREATE TABLE 'tblModels' ('modelsID' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,'makeKey' INTEGER, 'modelName' TEXT, 'modelKey' INTEGER)";
Cursor cursor = dbLocals.executeRawQuery(deleteQuery, null);
cursor.moveToFirst();
cursor = dbLocals.executeRawQuery(createQuery, null);
cursor.moveToFirst();
try {
JSONArray dicRecordSet = dict.getJSONArray("Recordset");
JSONObject dicRecords = dicRecordSet.getJSONObject(0);
JSONArray arrRecords = dicRecords.getJSONArray("Record");
for (int i = 0; i < arrRecords.length(); i++) {
JSONObject record = arrRecords.getJSONObject(i);
insertQuery = "INSERT INTO 'tblModels' VALUES(" + null + ", "
+ record.getString("MODMAKlMakeKey") + ", '"
+ record.getString("MODvc50Name").replaceAll("'", "''") + "', "
+ record.getString("MODlModelKey")
+")";
cursor = dbLocals.executeRawQuery(insertQuery, null);
cursor.moveToFirst();
}
} catch (JSONException e) {
e.printStackTrace();
}
cursor.close();
}
我的数据库一个管理器returns一个游标。
public Cursor executeRawQuery(String query, String[] selectionArgs) {
Cursor cursor = databaseConn.rawQuery(query, selectionArgs);
return cursor;
}
我做错了什么?
您应该在使用后关闭游标。在循环内部,您在每次迭代中都创建了一个游标,而没有关闭它。显然,打开游标的数量是有限制的,而您达到了该限制。
您不能重复使用游标变量,因为它覆盖了原来的变量,因此您不能关闭它:
Cursor cursor = dbLocals.executeRawQuery(deleteQuery, null);
然后
cursor = dbLocals.executeRawQuery(insertQuery, null);
第二个赋值意味着您无法关闭原始游标。
此外,您为什么要在此处创建 table?
编辑:
这样使用:
public void addModelsToDB(JSONObject dict){
String insertQuery = "";
String deleteQuery = "DROP TABLE IF EXISTS 'tblModels'";
String createQuery = "CREATE TABLE 'tblModels' ('modelsID' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,'makeKey' INTEGER, 'modelName' TEXT, 'modelKey' INTEGER)";
Cursor cursor = dbLocals.executeRawQuery(deleteQuery, null);
try {
cursor.moveToFirst();
cursor = dbLocals.executeRawQuery(createQuery, null);
cursor.moveToFirst();
} finally {
cursor.close();
}
try {
JSONArray dicRecordSet = dict.getJSONArray("Recordset");
JSONObject dicRecords = dicRecordSet.getJSONObject(0);
JSONArray arrRecords = dicRecords.getJSONArray("Record");
for (int i = 0; i < arrRecords.length(); i++) {
JSONObject record = arrRecords.getJSONObject(i);
insertQuery = "INSERT INTO 'tblModels' VALUES(" + null + ", "
+ record.getString("MODMAKlMakeKey") + ", '"
+ record.getString("MODvc50Name").replaceAll("'", "''") + "', "
+ record.getString("MODlModelKey")
+")";
cursor = dbLocals.executeRawQuery(insertQuery, null);
try {
cursor.moveToFirst();
} finally {
cursor.close();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
我是 运行 一个后台任务,它会下载一个 JSON 文件,解析它,然后将它添加到 SQLite 数据库的内容中。
我在运行时遇到了一些错误。
Caused by: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=728 (# cursors opened by this proc=728)
E/CursorWindow: Could not allocate CursorWindow '/data/data/com.mycompany.inventory/databases/dbInventory.sql' of size 2097152 due to error -12.
JSON 中有大约 1500 个项目。
这是我的异步任务调用的方法:
public void addModelsToDB(JSONObject dict){
String insertQuery = "";
String deleteQuery = "DROP TABLE IF EXISTS 'tblModels'";
String createQuery = "CREATE TABLE 'tblModels' ('modelsID' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,'makeKey' INTEGER, 'modelName' TEXT, 'modelKey' INTEGER)";
Cursor cursor = dbLocals.executeRawQuery(deleteQuery, null);
cursor.moveToFirst();
cursor = dbLocals.executeRawQuery(createQuery, null);
cursor.moveToFirst();
try {
JSONArray dicRecordSet = dict.getJSONArray("Recordset");
JSONObject dicRecords = dicRecordSet.getJSONObject(0);
JSONArray arrRecords = dicRecords.getJSONArray("Record");
for (int i = 0; i < arrRecords.length(); i++) {
JSONObject record = arrRecords.getJSONObject(i);
insertQuery = "INSERT INTO 'tblModels' VALUES(" + null + ", "
+ record.getString("MODMAKlMakeKey") + ", '"
+ record.getString("MODvc50Name").replaceAll("'", "''") + "', "
+ record.getString("MODlModelKey")
+")";
cursor = dbLocals.executeRawQuery(insertQuery, null);
cursor.moveToFirst();
}
} catch (JSONException e) {
e.printStackTrace();
}
cursor.close();
}
我的数据库一个管理器returns一个游标。
public Cursor executeRawQuery(String query, String[] selectionArgs) {
Cursor cursor = databaseConn.rawQuery(query, selectionArgs);
return cursor;
}
我做错了什么?
您应该在使用后关闭游标。在循环内部,您在每次迭代中都创建了一个游标,而没有关闭它。显然,打开游标的数量是有限制的,而您达到了该限制。
您不能重复使用游标变量,因为它覆盖了原来的变量,因此您不能关闭它:
Cursor cursor = dbLocals.executeRawQuery(deleteQuery, null);
然后
cursor = dbLocals.executeRawQuery(insertQuery, null);
第二个赋值意味着您无法关闭原始游标。
此外,您为什么要在此处创建 table?
编辑:
这样使用:
public void addModelsToDB(JSONObject dict){
String insertQuery = "";
String deleteQuery = "DROP TABLE IF EXISTS 'tblModels'";
String createQuery = "CREATE TABLE 'tblModels' ('modelsID' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,'makeKey' INTEGER, 'modelName' TEXT, 'modelKey' INTEGER)";
Cursor cursor = dbLocals.executeRawQuery(deleteQuery, null);
try {
cursor.moveToFirst();
cursor = dbLocals.executeRawQuery(createQuery, null);
cursor.moveToFirst();
} finally {
cursor.close();
}
try {
JSONArray dicRecordSet = dict.getJSONArray("Recordset");
JSONObject dicRecords = dicRecordSet.getJSONObject(0);
JSONArray arrRecords = dicRecords.getJSONArray("Record");
for (int i = 0; i < arrRecords.length(); i++) {
JSONObject record = arrRecords.getJSONObject(i);
insertQuery = "INSERT INTO 'tblModels' VALUES(" + null + ", "
+ record.getString("MODMAKlMakeKey") + ", '"
+ record.getString("MODvc50Name").replaceAll("'", "''") + "', "
+ record.getString("MODlModelKey")
+")";
cursor = dbLocals.executeRawQuery(insertQuery, null);
try {
cursor.moveToFirst();
} finally {
cursor.close();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}