I've got this piece of code that I'm trying to run in my Android app:
ServerDatabase.getInstance(ListServersActivity.this).serverDao().getAll().observe(ListServersActivity.this, new Observer<List<Server>>() {
@Override
public void onChanged(List<Server> servers) {
serverListAdapter.setServers(servers);
}
});
I'm trying to run that on the UI thread, so I'm getting this error that looks pretty straight forward and there are lots of entries about it in StackOverflow:
Cannot access database on the main thread since it may potentially lock the UI for a long period of time
Now, the problem with this and what makes it different from previous questions I think, is that I'm running it in the main thread on purpose calling runOnUiThread because when I was doing it in a background thread I've got this other error:
Cannot invoke observe on a background thread
So screwed if I run it on the main thread, and screwed if I run it on a background thread. How do I solve this conundrum?
Adding more info, ServerDao is a Room Dao interface so the actual implemenation is generated by Room. This is the declaration of the involved method:
public interface ServerDao {
@Query("SELECT * FROM server ORDER BY id ASC")
LiveData<List<Server>> getAll();
// ...
}
This is the stack when running in the background thread:
2020-03-13 13:36:37.684 24241-24939/com.daon.identityx.docscan E/AndroidRuntime: FATAL EXCEPTION: Thread-13 Process: com.daon.identityx.docscan, PID: 24241 java.lang.IllegalStateException: Cannot invoke observe on a background thread at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:443) at androidx.lifecycle.LiveData.observe(LiveData.java:171) at com.daon.identityx.docscan.ui.activity.ListServersActivity.initRecyclerViewAdapter(ListServersActivity.java:92) at com.daon.identityx.docscan.ui.activity.ListServersActivity.access$000(ListServersActivity.java:33) at com.daon.identityx.docscan.ui.activity.ListServersActivity$1.run(ListServersActivity.java:62) at java.lang.Thread.run(Thread.java:764) 2020-03-13 13:36:37.856 24241-24939/com.daon.identityx.docscan E/UncaughtException: java.lang.IllegalStateException: Cannot invoke observe on a background thread at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:443) at androidx.lifecycle.LiveData.observe(LiveData.java:171) at com.daon.identityx.docscan.ui.activity.ListServersActivity.initRecyclerViewAdapter(ListServersActivity.java:92) at com.daon.identityx.docscan.ui.activity.ListServersActivity.access$000(ListServersActivity.java:33) at com.daon.identityx.docscan.ui.activity.ListServersActivity$1.run(ListServersActivity.java:62) at java.lang.Thread.run(Thread.java:764) 2020-03-13 13:36:37.899 24241-24595/com.daon.identityx.docscan E/CrashlyticsCore: Unexpected method invoked on AppMeasurement.EventListener: onEvent(java.lang.String, java.lang.String, android.os.Bundle, java.lang.Long); returning null 2020-03-13 13:36:54.223 24960-25084/com.daon.identityx.docscan E/FirebaseCrash: Unable to parse Json response string to get message: No value for crashes
And this is the stack when running in the UI thread:
2020-03-13 13:45:17.552 26410-26410/com.daon.identityx.docscan E/AndroidRuntime: FATAL EXCEPTION: main Process: com.daon.identityx.docscan, PID: 26410 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.daon.identityx.docscan/com.daon.identityx.docscan.ui.activity.ListServersActivity}: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7050) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:267) at androidx.room.RoomDatabase.query(RoomDatabase.java:323) at androidx.room.util.DBUtil.query(DBUtil.java:83) at com.daon.identityx.docscan.database.models.ServerDao_Impl.getCount(ServerDao_Impl.java:300) at com.daon.identityx.docscan.repository.ServerDatabase.addDefaultDataIfEmpty(ServerDatabase.java:30) at com.daon.identityx.docscan.repository.ServerDatabase.getInstance(ServerDatabase.java:23) at com.daon.identityx.docscan.ui.activity.ListServersActivity.initRecyclerViewAdapter(ListServersActivity.java:88) at com.daon.identityx.docscan.ui.activity.ListServersActivity.onCreate(ListServersActivity.java:60) at android.app.Activity.performCreate(Activity.java:7327) at android.app.Activity.performCreate(Activity.java:7318) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7050) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 2020-03-13 13:45:17.694 26410-26410/com.daon.identityx.docscan E/UncaughtException: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.daon.identityx.docscan/com.daon.identityx.docscan.ui.activity.ListServersActivity}: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7050) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:267) at androidx.room.RoomDatabase.query(RoomDatabase.java:323) at androidx.room.util.DBUtil.query(DBUtil.java:83) at com.daon.identityx.docscan.database.models.ServerDao_Impl.getCount(ServerDao_Impl.java:300) at com.daon.identityx.docscan.repository.ServerDatabase.addDefaultDataIfEmpty(ServerDatabase.java:30) at com.daon.identityx.docscan.repository.ServerDatabase.getInstance(ServerDatabase.java:23) at com.daon.identityx.docscan.ui.activity.ListServersActivity.initRecyclerViewAdapter(ListServersActivity.java:88) at com.daon.identityx.docscan.ui.activity.ListServersActivity.onCreate(ListServersActivity.java:60) at android.app.Activity.performCreate(Activity.java:7327) at android.app.Activity.performCreate(Activity.java:7318) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7050) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 2020-03-13 13:45:17.732 26410-26729/com.daon.identityx.docscan E/CrashlyticsCore: Unexpected method invoked on AppMeasurement.EventListener: onEvent(java.lang.String, java.lang.String, android.os.Bundle, java.lang.Long); returning null 2020-03-13 13:45:26.315 27259-27416/com.daon.identityx.docscan E/FirebaseCrash: Unable to parse Json response string to get message: No value for crashes