I sometimes get SQLiteMisuseException when row is being inserted. Application works perfectly on hundreds of devices but on one with android 3.1 there is an SQLite exception. Stack trace:
android.database.sqlite.SQLiteMisuseException: error code 21: not an error
at android.database.sqlite.SQLiteStatement.native_executeInsert(Native Method)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:112)
This is a code which invoking executeInsert():
final SQLiteStatement insUrlStmt = db.compileStatement("insert into urls (url,idx) values (?,?)");
insUrlStmt.bindString(1, url)
insUrlStmt.bindLong(2, idx);
return insUrlStmt.executeInsert();
Declaration of db field:
private final SQLiteDatabase db;
Initialization of db field (this is invoked once in onCreate() of Application class object) and reference to DataHelper is stored statically in application instance:
public DataHelper(Context context) {db = new OpenHelper(context).getWritableDatabase(); }
OpenHelper constructor:
protected OpenHelper(Context context)
{
super(context, "database.db", null, 1);
}
I've already read this question: Android SQLite error code 21 and searched for things mentioned there.
SQLiteDatabase (db field) is opened only once and it is never closed directly from application code. Multi-thread access should not be a problem because first thing in executeInsert() method is locking database (I checked in source code of android 2.1, so I assume that this behavior didn't changed in 3.1).
03-14 19:54:33.360 I/SqliteDatabaseCpp(15953): sqlite returned: error code = 21, msg = API called with NULL prepared statement, db=/data/data/<package_name>/databases/database.db 03-14 19:54:33.360 I/SqliteDatabaseCpp(15953): sqlite returned: error code = 21, msg = misuse at line 58940 of [8609a15dfa], db=/data/data/<package_name>/databases/database.db