I have an app that uses ContentProvider to access SQLite. An instance of SQLiteOpenHelper is created in providers onCreate:
@Override
public boolean onCreate() {
final Context context = getContext();
mDBHelper = new MyDatabase(context);
return true;
}
SQLiteDatabase instances retrieved in methods insert/update/delete/query are not manually closed. None of these methods are marked synchronized. ContentProvider is accessed from multiple threads started from UI and services.
Sample stacktrace:
android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 3850)
at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(Native Method)
at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java:734)
at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java:754)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:64)
at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1574)
at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1520)
at com.sample.provider.MyProvider.update(SourceFile:0)
at android.content.ContentProvider$Transport.update(ContentProvider.java:260)
at android.content.ContentResolver.update(ContentResolver.java:1040)
Things worked fine up to the moment when I added a class that serializes writes to certain tables using a Handler initialized by Looper from HandlerThread. After this I started seeing plenty of SQLiteDiskIOExceptions with error codes 3850 and 0 (not an error?). Interestingly 90% of these crashes occur with Nexus 4 and on a handful of other devices.
I have been running Unit tests trying to simulate the condition but have been unable to reproduce the problem. There are other questions that already discuss related issues (e.g. here: Synchronize access to Content Provider) but to me the original cause for this error seems still a bit unclear. So what really are the reasons for error 3850?