Android Wear-Run Room数据库指令在一个单独的线程上使用Java



我写了一个简单的应用程序,可以检测运行Android Wear OS的智能手表上传感器的光电体积描记图(PPG(信号。我目前正试图使用Room记录该数据,以便访问数据并对其进行分析。当我试图将数据插入数据库时遇到问题,导致以下错误:

2022-01-08 14:15:13.435 5482-5482/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ppg_extraction_final, PID: 5482
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:469)
at androidx.room.RoomDatabase.beginTransaction(RoomDatabase.java:553)
at com.example.ppg_extraction_final.db.PpgDao_Impl.add(PpgDao_Impl.java:58)
at com.example.ppg_extraction_final.ui.MainActivity.writePpgData(MainActivity.java:98)
at com.example.ppg_extraction_final.ui.MainActivity.onSensorChanged(MainActivity.java:72)
at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:833)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:326)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:6680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

我知道我收到这个错误是因为我试图在主线程上操作数据库,这会导致我的UI速度减慢。我还知道Kotlin协同程序为这个问题提供了一个很好的解决方案,只需要相对较少的样板。然而,在用Java编写程序后,我有点迷失了纠正这个错误的最佳方法。我有可能在我当前的应用程序结构中以某种方式实现kotlin协同程序吗?是否值得将整个应用程序迁移到kotlin?在java中还有其他方法可以执行此操作吗?

以下是我的主要活动的相关部分。PpgDatabase、PpgData和PpgDao分别指我的数据库、实体和DAO类。这些都在自己的文件中。如果需要这些代码,请告诉我!

public class MainActivity extends Activity implements SensorEventListener {
private TextView textView;
private SensorManager sensorManager;
PpgDatabase ppgDatabase;
PpgDao ppgDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
com.example.ppg_extraction_final.databinding.ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
textView = findViewById(R.id.dataText);
// Instantiate sensor manager
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// Obtain db instance
ppgDatabase = DatabaseClient.getInstance(getApplicationContext()).getPpgDatabase();
// Instantiate ppg dao
ppgDao = ppgDatabase.getPpgDao();
}
public void onStartClick(View view) {
// Begin listening for sensor events on start click
// 65572 = PPG sensor type
sensorManager.registerListener(this, sensorManager.getDefaultSensor(65572),
sensorManager.SENSOR_DELAY_NORMAL);
}
public void onStopClick(View view) {
// Stop listening for sensor events on stop click
sensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event) {
// 65572 = PPG sensor type
if (event.sensor.getType() == 65572)
writePpgData(ppgDao, event);
}
public void writePpgData(PpgDao ppgDao, SensorEvent event) {
// Function for adding sensor event to db
PpgData ppgData = new PpgData();
ppgData.setCh0(event.values[0]);
ppgData.setCh1(event.values[1]);
ppgDao.add(ppgData);
}
}

如果有任何建议,我将不胜感激。谢谢

我认为Kotlin是首选。

但由于这个问题本身不应该阻止你这么长时间,我认为你应该能够使用Executors。

查看谷歌的房间基本样本:

特别是数据库初始化

这里executors.diskIO()用于在后台线程上与数据库交互

遗嘱执行人在这里有定义。

相关内容

  • 没有找到相关文章

最新更新