【问题标题】:Using a handler for Android Room on a separate thread在单独的线程上使用 Android Room 的处理程序
【发布时间】:2018-05-31 17:27:25
【问题描述】:

我目前正在使用 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 在新线程/looper 上运行,并且 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.

我做错了什么?

【问题讨论】:

    标签: android multithreading android-room android-looper


    【解决方案1】:

    我发现了错误:

    dispatchMessage(msg) 覆盖任何线程并手动调用 handleMessage 方法,而发送消息尊重处理程序的循环器/线程。

    解决方案:

    将 dispatchMessage(msg) 替换为 sendMessage(msg)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 2015-08-09
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多