在单独的线程

时间:2018-05-31 17:27:26

标签: android multithreading android-room android-looper

我目前正在使用Android Room在Android上存储一些小数据。理论上我使用allowMainThreadQueries()应该没问题,因为我的所有数据都很小,但是为了防范我的程序,我试图将所有调用移到一个单独的线程中。截至目前,我在AppConfig中有一个静态处理程序,该类在应用程序的初始启动时初始化,并且可见应用范围:

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

DbHandler是一个扩展Handler的自定义类,具有以下构造函数:

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();
}

它会覆盖handleMessage(Message msg),并根据msg.what执行各种插入/更新/删除操作,所有操作都无效。

在某些Activity的UI线程中,我调用此代码:

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

我的理解是,由于Handler正在一个新的线程/循环器上运行,并且因为UI线程没有等待任何输出,所以不应该有任何问题。但是,无论何时我调用此代码,我都会得到相同的错误,就像我直接在ui线程中访问数据库一样:

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

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我发现了错误:

dispatchMessage(msg)覆盖所有线程并手动调用handleMessage方法,而send message则尊重处理程序的looper / thread。

解决方案:

用sendMessage(msg)替换dispatchMessage(msg)