I discovered in my project that the close() function in the SQLiteDatabase implementation on Android throws a NullPointerException when running multiple threads that open the database, insert data, and then close the database. Everything runs smoothly unless I allow each thread to close() after inserting into the database.
Here is an example of what one of the writing threads might look like
ContentValues values = new ContentValues();
values.put(CallDetailsStorageConstants.COLUMN_NAME_REMOTE_NAME_IDX, (String) "");
values.put(CallDetailsStorageConstants.COLUMN_NAME_REMOTE_MEETINGID_IDX, (String) "");
CalculonDatabase callDetailsOpenHelper = CalculonDatabase.getInstance(mContext);
SQLiteDatabase dbw = callDetailsOpenHelper.getWritableDatabase();
long rowid = 0;
try {
rowid = dbw.insertWithOnConflict(CallDetailsTable.CALL_DETAILS_TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
} catch (SQLiteConstraintException e) {
e.printStackTrace();
} finally {
dbw.close();
}
You can see that at the end a call to close() is made. When running multiple threads I get this exception.
11-03 03:39:26.128: E/AndroidRuntime(977): FATAL EXCEPTION: Thread-17
11-03 03:39:26.128: E/AndroidRuntime(977): java.lang.NullPointerException
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:283)
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:96)
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1933)
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1864)
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:636)
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:551)
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:240)
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:111)
11-03 03:39:26.128: E/AndroidRuntime(977): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1737)
11-03 03:39:26.128: E/AndroidRuntime(977): at com.smash.DBWritingThread.run(DBWritingThread.java:50)
My question then is why does this error happen only when using the close() function? Also, is it ok to use close() at a much later time or possibly never?
Any tips with this issue are very much appreciated.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…