As mentioned here, the SQLiteDatabase close () function that throws a NullPointerException on multiple threads
The reason for your error may be that you are at some point closing the database. Perhaps at the same time, when a task that failed, was not completed.
I followed stacktrace several times, and it is something like this:
AlbumsData.insertOrIgnore(AlbumsData.java:89)
You call insertWithOnConflict , which creates the resulting sql string ( "INSERT OR IGNORE INTO..." ), then wraps this along with the values โโfrom your ContentValues in SQLiteStatement .SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1844) - the resulting statement must be executed nowSQLiteStatement.executeInsert(SQLiteStatement.java:112) - before the actual insert occurs, the database must receive a lock.SQLiteStatement.acquireAndLock(SQLiteStatement.java:247) - here some checks occur, the database object until I see the zero point. The code decides that it should start the transaction. The database object itself, as far as I can see, is not locked at this point.SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:605) - just a redirectSQLiteDatabase.beginTransaction(SQLiteDatabase.java:690) - after some checks (not sure if the database should exist here), it will try to execute execSQL("BEGIN IMMEDIATE;")SQLiteDatabase.execSQL(SQLiteDatabase.java:1965) - just goSQLiteDatabase.executeSql(SQLiteDatabase.java:2025) - creates another SQLiteStatement from "BEGIN IMMEDIATE; SQLiteStatement This should be done nowSQLiteStatement.executeUpdateDelete(SQLiteStatement.java:96) - starts by checking for database locks, everything seems to be in order, and the database should not be null here. Then the instruction is executed and, finally, the database should be unlocked again.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:290) - Cleans up some things and ultimately fails with NPE because the database is null .
Line numbers do not match, so there are probably vendor modifications / additions in this code.
As you can see, the code drops to the actual use of the data you provided. He was going to do
BEGIN TRANSACTION IMMEDIATE;
This makes it, in my opinion, a framework. The database object that is internally processed there should not be null somewhere down the line, especially when it seems that it was no longer null on the stack.
I also think it is possible that the reason for this may be another hidden exception. There are many try { /* do stuff */ } finally { /* clean up */ } blocks inside the code, and the finally part will execute even if the try part try an exception. Now, the finally block can raise another exception, and the result will be AFAIK so that the original exception is replaced with the new exception from the finally block.
Especially executeUpdateDelete() is similar to
try { acquireAndLock(WRITE); // actual statement execution } finally { releaseAndUnlock(); }
if the database is closed at this point, acquireAndLock or any code in the try part may fail, and this may leave the database object null , causing releaseAndUnlock to crash again. You should get the same stack.
Also, do not make empty catch blocks, such as catch (SQLiteException e) { /* empty */ } . Record them with ACRA, if possible / you will not.