我一直在尝试修复过去2天内的SQLiteCantOpenDatabaseException错误,但无济于事。 我正在通过一个大小为4750的arrayList进行迭代,并在每次迭代时查询数据库。
/**
* This method generates edge sets from wifiList then updates the EdgeTable.
* Step1: Check if edge already exists in EdgeTable.
* Step2: if step1 is true then increment edge weight by 1
* otherwise insert a new edge into EdgeTable and set its default weight to 1
*
* @param wifiList List containing wifiIds(hash value of Access Points macAddresses)
* @param inervalID int intervall ID
**/
public static synchronized void updateEdgeTable(ArrayList<String> wifiList, int inervalID) {
ArrayList<ArrayList<String>> edgeList = new ArrayList<>();
//generating edge pairs from wifiList
for (int i = 0; i < wifiList.size() - 1; i++) {
for (int j = i + 1; j < wifiList.size(); j++) {
edgeList.add(createEdge(wifiList.get(i), wifiList.get(j)));
}
} //[end 1st for loop]
// adding edges to the edge table
for (ArrayList<String> edge : edgeList) {
/*get edge from EdgeTable, cursor is empty if edge does not exist in the table*/
Cursor cursor = getRow(edge.get(0), edge.get(1), inervalID);
if (cursor != null && cursor.moveToFirst()) {
/*if cursor is not empty, then edge already exists, hence increment the edge weight by 1*/
try {
updateEdgeWeight(edge.get(0), edge.get(1), cursor.getInt(cursor.getColumnIndex(EdgeTable.COLUMN_EdgeWeight)) + 1, inervalID);
/* TODO: 10/18/16 : there is an error here : android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14),
(14) statement aborts at 18: [select * from EDGE_TABLE where INTERVAL_ID= 2 and SOURCE= "3Co/YY" and TARGET= "cinaVR"] unable to open database file */
} catch (Exception e) {
e.printStackTrace();
}
cursor.close();
} else {
/*if cursor is empty then edge does not exist, hence add new edge with default weight =1*/
EdgeTable entry = new EdgeTable();
entry.setIntervalID(inervalID);
entry.setSource(edge.get(0));
entry.setTarget(edge.get(1));
entry.setEdgeWeight(1);
EdgeRepository.insert(entry);
cursor.close();
} //[end if]
} //[end 2nd for loop]
} //[end of updateEdgeTable() method ]
/**
* This method performs the following select query:
* --> select * from EDGE_TABLE where INTERVAL_ID= intervalID and SOURCE= sourceNode and TARGET= targetNode
* Example: select * from EDGE_TABLE where INTERVAL_ID= 1 and SOURCE= "H0LaCI" and TARGET= "RZyhnJ"
* @param sourceNode the source node
* @param targetNode the target node
* @param inervalID interval ID
*@return A Cursor containing the query result
* */
public static synchronized Cursor getRow(String sourceNode, String targetNode, int inervalID) {
Cursor cursor = checkIfEdgeExist(sourceNode, targetNode, inervalID);
if (cursor.moveToFirst() == false) {
SQLiteDatabase db = DatabaseManager.getInstance().openDatabase();
cursor = db.rawQuery("select * from "
+ EdgeTable.TABLE + " where "
+ EdgeTable.COLUMN_IntervalID + "= " + inervalID + " and "
+ EdgeTable.COLUMN_Source + "= " + "\"" + targetNode + "\"" + " and "
+ EdgeTable.COLUMN_Target + "= " + "\"" + sourceNode + "\""
, null);
}
DatabaseManager.getInstance().closeDatabase();
return cursor;
}
10-17 20:34:14.333 8028-8078 E/SQLiteLog: (14) cannot open file at line 30188 of [bda77dda96]
10-17 20:34:14.333 8028-8078 E/SQLiteLog: (14) os_unix.c:30188: (24) open(/data/user/0/lu.uni.myappmain.senspro/databases) -
10-17 20:34:14.340 8028-8078 E/SQLiteLog: (14) cannot open file at line 32456 of [bda77dda96]
10-17 20:34:14.341 8028-8078 E/SQLiteLog: (14) os_unix.c:32456: (24) open(/data/user/0/lu.uni.myappmain.senspro/databases/ActivityRecognitionDB.db-journal) -
10-17 20:34:14.341 8028-8078 E/SQLiteLog: (14) cannot open file at line 32456 of [bda77dda96]
10-17 20:34:14.341 8028-8078 E/SQLiteLog: (14) os_unix.c:32456: (24) open(/data/user/0/lu.uni.myappmain.senspro/databases/ActivityRecognitionDB.db-journal) -
10-17 20:34:14.341 8028-8078 E/SQLiteLog: (14) statement aborts at 18: [select * from EDGE_TABLE where INTERVAL_ID= 1 and SOURCE= "H0LaCI" and TARGET= "RZyhnJ"] unable to open database file
10-17 20:34:14.342 8028-8078 E/SQLiteQuery: exception: unable to open database file (code 14); query: select * from EDGE_TABLE where INTERVAL_ID= 1 and SOURCE= "H0LaCI" and TARGET= "RZyhnJ"
10-17 20:34:14.343 8028-8078 E/AndroidRuntime: FATAL EXCEPTION: Thread-4
Process: lu.uni.myappmain.senspro, PID: 8028
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:845)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:219)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:258)
at lu.uni.myappmain.senspro.data.repository.EdgeRepository.updateEdgeTable(EdgeRepository.java:111)
at lu.uni.myappmain.senspro.MyMainService$3.run(MyMainService.java:365)
at java.lang.Thread.run(Thread.java:761)
答案 0 :(得分:0)
我发现了我的这个bug版本的几个原因。
不关闭游标。 Cursor是一个重量级资源,你不能一次打开它们太多。
同步数据库资源。 SqliteDatabase实现中没有完整的线程支持。
最简单的解决方案......
synchronized (DatabaseManager.getInstance())
Cursor cursor = checkIfEdgeExist(sourceNode, targetNode, inervalID);
if (cursor.moveToFirst() == false) {
SQLiteDatabase db = DatabaseManager.getInstance().openDatabase();
cursor = db.rawQuery("select * from "
+ EdgeTable.TABLE + " where "
+ EdgeTable.COLUMN_IntervalID + "= " + inervalID + " and "
+ EdgeTable.COLUMN_Source + "= " + "\"" + targetNode + "\"" + " and "
+ EdgeTable.COLUMN_Target + "= " + "\"" + sourceNode + "\""
, null);
}
DatabaseManager.getInstance().closeDatabase();
}
我有一个使用SQLiteOpenHelper的数据库。
在这个我确定是单身的课程中,我添加了以下代码......
private ReentrantReadWriteLock mLock = new ReentrantReadWriteLock();
public Lock readLock() {
return mLock.readLock();
}
public Lock writeLock() {
return mLock.writeLock();
}
然后,每次我使用数据库时,都检查了只读或读写访问,正确调用....
StorageContract.DbHelper helper = StorageContract.DbHelper .getInstance(this);
SQLiteDatabase db = helper.getReadableDatabase();
helper.readLock().lock();
try {
// do some read only operation on the database.
}
finally {
helper.readLock().unlock();
}
答案 1 :(得分:0)
return $http.get(
"AdvancedSearch/SearchUsers",
{
params: {
//search: {
SearchTerms: searchTerms,
Markets: markets,
Roles: roles,
Capabilities: capabilities,
Groups: groups,
Industries: experience,
Skills: skills,
Technologies: technologies,
Certifications: certification
//}
}
}
);