您当前的代码不是线程安全的Runnable
使用 UI 线程写入的相同数组。一旦你打电话executor.execute(insertHandler);
无法保证 UI 线程不会收到另一个传感器事件并更改之前的数组值之一Runnable
将它们写入数据库。看来你明白这部分了。
为了解决这个问题,我根本不建议使用同步块,因为您似乎只想写出数组中存储的任何值diffTime > POLL_FREQUENCY
. The onSensorChanged(...)
方法本身只会在代码中的 UI 线程上调用,因此您不必担心另一个线程在此方法中更改数组的值。
综上所述,您可以做的是将数组的当前值存储在您的新实例中Runnable
班级。我知道您在上一篇文章中建议使用相同的实例,但这不会产生明显的差异。您甚至可以通过打开 Android Monitor 进行验证,并在应用程序运行时检查内存使用情况。通过存储当前值,现在不再重要onSensorChanged()
在写出数据之前再次调用,因为您已经拥有所需数据的副本,并且不会更改。
这是我在代码中建议的内容:
class InsertHandler implements Runnable {
final float[] accelerometerMatrix;
final float[] accelerometerWorldMatrix;
final float[] gyroscopeMatrix;
final float[] gravityMatrix;
final float[] magneticMatrix;
final float[] rotationMatrix;
public InsertHandler(float[] accelerometerMatrix, float[] accelerometerWorldMatrix,
float[] gyroscopeMatrix, float[] gravityMatrix,
float[] magneticMatrix, float[] rotationMatrix) {
this.accelerometerMatrix = accelerometerMatrix;
this.accelerometerWorldMatrix = accelerometerWorldMatrix;
this.gyroscopeMatrix = gyroscopeMatrix;
this.gravityMatrix = gravityMatrix;
this.magneticMatrix = magneticMatrix;
this.rotationMatrix = rotationMatrix;
}
public void run() {
// use class field arrays values and insert into db
}
}
然后当你添加Runnable
to the executor
use:
Runnable insertHandler = new InsertHandler(accelerometerMatrix, accelerometerWorldMatrix,
gyroscopeMatrix, gravityMatrix, magneticMatrix, rotationMatrix);
executor.execute(insertHandler);