Android Wear - 运行 在单独的线程上使用 Java 房间数据库指令?
Android Wear - Run Room Database Instructions on a Separate Thread using Java?
我编写了一个简单的应用程序,用于检测来自智能手表 运行ning 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 中是否有其他方法可以执行此操作?
这是我的 MainActivity 的相关部分。 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。
查看 Room Basic Sample by Google:
这里executors.diskIO()
用于在后台线程上与DataBase交互
执行器已定义 here。
我编写了一个简单的应用程序,用于检测来自智能手表 运行ning 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 中是否有其他方法可以执行此操作?
这是我的 MainActivity 的相关部分。 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。
查看 Room Basic Sample by Google:
这里executors.diskIO()
用于在后台线程上与DataBase交互
执行器已定义 here。