Search code examples
androidmultithreadingandroid-roomandroid-looper

Using a handler for Android Room on a separate thread


I am currently using Android Room to store some small data on Android. In theory I should have no problem using allowMainThreadQueries() since all of my data is small, but in order to future-proof my program I am trying to move all of my calls into a separate thread. As of right now I have a static Handler in AppConfig a class that is initialized on the app's initial launch and is visible app wide:

HandlerThread thread = new HandlerThread("dbHandlerThread");
thread.start();
serviceHandler = new DbHandler(thread.getLooper(),lApp.getBaseContext(),dbName);

DbHandler is a custom class that extends Handler and has the following constructor:

DbHandler(Looper looper, Context context, String dbName) {
    super(looper);

    AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, dbName)
            .fallbackToDestructiveMigration().build();

    coDao = db.countOrderDao();
    plDao = db.productListDao();
    pDao = db.productDao();
}

It overrides handleMessage(Message msg) and depending on the msg.what performs a variety of insert/update/delete operations all of which are void.

In the UI thread in some Activity I call this code:

Message msg = Message.obtain();
msg.what = AppConfig.SAVE;
//insert some data and args
AppConfig.serviceHandler.dispatchMessage(msg);

My understanding is that since the Handler is running on a new thread/looper and since the UI thread is not waiting for any output there should not be any problem with this. However, anytime I call this code I get the same error as if I was accessing the database directly in the ui thread:

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

What am I doing wrong?


Solution

  • I found the error:

    dispatchMessage(msg) overrides any threads and manually calls the handleMessage method, while send message respects the looper/thread for the handler.

    Solution:

    Replace dispatchMessage(msg) with sendMessage(msg)