我目前正在使用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.
我做错了什么?
答案 0 :(得分:0)
我发现了错误:
dispatchMessage(msg)覆盖所有线程并手动调用handleMessage方法,而send message则尊重处理程序的looper / thread。
解决方案:
用sendMessage(msg)替换dispatchMessage(msg)