If we are running Usecase tests with ROBOTIUM, then the database can be pulled and Activities finished abruptly, while AsyncTasks keep running on other threads. This leads to SQLiteExceptions (and possibly others). Fixed with a static flag ROBOTIUM_RUNNING in Collectionista.java that will catch these. I should switch this flag before running the tests.
Disadvantage is of course that you are for a small part not testing what will happen in the field anymore. Related:
http://stackoverflow.com/questions/12091878/can-i-determine-if-an-activity-has-running-asynctasks
http://stackoverflow.com/questions/11831894/how-can-i-ensure-an-asynctask-is-completed-before-my-activity-is-killed
This SQLiteException can hit seemingly random, so on a rerun (especially a partial one) it will not happen in the same testcase.
Errors on logcat:
before:
08-18 12:15:00.929: E/Cursor(2310): Finalizing a Cursor that has not been deactivated or closed. database = /data/data/net.lp.collectionista/databases/collectionista.db, table = collections, query = SELECT _id, subtype FROM collections WHERE (_id=1) ORDER BY modified DESC
08-18 12:15:00.929: E/Cursor(2310): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
08-18 12:15:00.929: E/Cursor(2310): at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210)
08-18 12:15:00.929: E/Cursor(2310): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
08-18 12:15:00.929: E/Cursor(2310): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
08-18 12:15:00.929: E/Cursor(2310): at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:330)
08-18 12:15:00.929: E/Cursor(2310): at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:280)
08-18 12:15:00.929: E/Cursor(2310): at net.lp.collectionista.providers.ProductContentProvider.query(ProductContentProvider.java:750)
08-18 12:15:00.929: E/Cursor(2310): at android.content.ContentProvider$Transport.query(ContentProvider.java:163)
08-18 12:15:00.929: E/Cursor(2310): at android.content.ContentResolver.query(ContentResolver.java:245)
08-18 12:15:00.929: E/Cursor(2310): at net.lp.collectionista.providers.FacadeContentProvider.query(FacadeContentProvider.java:580)
08-18 12:15:00.929: E/Cursor(2310): at android.content.ContentProvider$Transport.query(ContentProvider.java:163)
08-18 12:15:00.929: E/Cursor(2310): at android.content.ContentResolver.query(ContentResolver.java:245)
08-18 12:15:00.929: E/Cursor(2310): at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:49)
08-18 12:15:00.929: E/Cursor(2310): at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:35)
08-18 12:15:00.929: E/Cursor(2310): at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240)
08-18 12:15:00.929: E/Cursor(2310): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
08-18 12:15:00.929: E/Cursor(2310): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
08-18 12:15:00.929: E/Cursor(2310): at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
08-18 12:15:00.929: E/Cursor(2310): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-18 12:15:00.929: E/Cursor(2310): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-18 12:15:00.929: E/Cursor(2310): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-18 12:15:00.929: E/Cursor(2310): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-18 12:15:00.929: E/Cursor(2310): at java.lang.Thread.run(Thread.java:1096)
08-18 12:15:00.979: E/ResourceType(2310): Style contains key with bad entry: 0x010102cd
08-18 12:15:01.209: E/AndroidRuntime(2310): FATAL EXCEPTION: ModernAsyncTask #4
real cause:
08-18 12:15:01.209: E/AndroidRuntime(2310): java.lang.RuntimeException: An error occured while executing doInBackground()
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:137)
08-18 12:15:01.209: E/AndroidRuntime(2310): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-18 12:15:01.209: E/AndroidRuntime(2310): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-18 12:15:01.209: E/AndroidRuntime(2310): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-18 12:15:01.209: E/AndroidRuntime(2310): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-18 12:15:01.209: E/AndroidRuntime(2310): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-18 12:15:01.209: E/AndroidRuntime(2310): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-18 12:15:01.209: E/AndroidRuntime(2310): at java.lang.Thread.run(Thread.java:1096)
08-18 12:15:01.209: E/AndroidRuntime(2310): Caused by: android.database.sqlite.SQLiteException: no such table: collections <--Database was pulled before this (second) stage could happen in the still running AsyncTask
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.database.sqlite.SQLiteQuery.native_fill_window(Native Method)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:70)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:283)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:264)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.content.ContentResolver.query(ContentResolver.java:251)
08-18 12:15:01.209: E/AndroidRuntime(2310): at net.lp.collectionista.providers.FacadeContentProvider.query(FacadeContentProvider.java:595) <--Fixed here with a workaround
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.content.ContentProvider$Transport.query(ContentProvider.java:163)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.content.ContentResolver.query(ContentResolver.java:245)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:49)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:35)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:240)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:51)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:40)
08-18 12:15:01.209: E/AndroidRuntime(2310): at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:123)
08-18 12:15:01.209: E/AndroidRuntime(2310): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-18 12:15:01.209: E/AndroidRuntime(2310): ... 4 more