在单独的线程上使用 Android Room 的处理程序
Using a handler for Android Room on a separate thread
我目前正在使用 Android Room 在 Android 上存储一些小数据。理论上我使用 allowMainThreadQueries() 应该没有问题,因为我所有的数据都很小,但为了让我的程序面向未来,我试图将我的所有调用移动到一个单独的线程中。截至目前,我在 AppConfig 中有一个静态处理程序 class,它在应用程序的初始启动时初始化并且在应用程序范围内可见:
HandlerThread thread = new HandlerThread("dbHandlerThread");
thread.start();
serviceHandler = new DbHandler(thread.getLooper(),lApp.getBaseContext(),dbName);
DbHandler 是自定义的 class,它扩展了 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 执行各种 insert/update/delete 操作,所有这些操作都是无效的。
在一些Activity的UI线程中我调用这段代码:
Message msg = Message.obtain();
msg.what = AppConfig.SAVE;
//insert some data and args
AppConfig.serviceHandler.dispatchMessage(msg);
我的理解是,由于处理程序是 运行 在新的 thread/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.
我做错了什么?
我发现错误:
dispatchMessage(msg) 覆盖任何线程并手动调用 handleMessage 方法,而发送消息尊重处理程序的 looper/thread。
解决方案:
将 dispatchMessage(msg) 替换为 sendMessage(msg)
我目前正在使用 Android Room 在 Android 上存储一些小数据。理论上我使用 allowMainThreadQueries() 应该没有问题,因为我所有的数据都很小,但为了让我的程序面向未来,我试图将我的所有调用移动到一个单独的线程中。截至目前,我在 AppConfig 中有一个静态处理程序 class,它在应用程序的初始启动时初始化并且在应用程序范围内可见:
HandlerThread thread = new HandlerThread("dbHandlerThread");
thread.start();
serviceHandler = new DbHandler(thread.getLooper(),lApp.getBaseContext(),dbName);
DbHandler 是自定义的 class,它扩展了 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 执行各种 insert/update/delete 操作,所有这些操作都是无效的。
在一些Activity的UI线程中我调用这段代码:
Message msg = Message.obtain();
msg.what = AppConfig.SAVE;
//insert some data and args
AppConfig.serviceHandler.dispatchMessage(msg);
我的理解是,由于处理程序是 运行 在新的 thread/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.
我做错了什么?
我发现错误:
dispatchMessage(msg) 覆盖任何线程并手动调用 handleMessage 方法,而发送消息尊重处理程序的 looper/thread。
解决方案:
将 dispatchMessage(msg) 替换为 sendMessage(msg)