- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这是我的问题的后续:Android thread runnable performance
我在思考应用程序的同步方法时遇到了一些困难
我轮询传感器并在传感器值发生变化时将其存储到数组中
float[] accelerometerMatrix = new float[3];
float[] accelerometerWorldMatrix = new float[3];
float[] gyroscopeMatrix = new float[3];
float[] gravityMatrix = new float[3];
float[] magneticMatrix = new float[3];
float[] rotationMatrix = new float[9];
class InsertHandler implements Runnable {
public void run() {
//get values from arrays and insert into db
}
}
public void onSensorChanged(SensorEvent event) {
sensor = event.sensor;
int i = sensor.getType();
if (i == MainActivity.TYPE_ACCELEROMETER) {
accelerometerMatrix = event.values;
} else if (i == MainActivity.TYPE_GYROSCOPE) {
gyroscopeMatrix = event.values;
} else if (i == MainActivity.TYPE_GRAVITY) {
gravityMatrix = event.values;
} else if (i == MainActivity.TYPE_MAGNETIC) {
magneticMatrix = event.values;
}
long curTime = System.currentTimeMillis();
long diffTime = (curTime - lastUpdate);
// only allow one update every POLL_FREQUENCY.
if(diffTime > POLL_FREQUENCY) {
lastUpdate = curTime;
//insert into database in background thread
executor.execute(insertHandler);
}
}
每隔 10 毫秒,我的应用程序将获取当前传感器值(来自数组)并使用单线程执行程序将它们插入数据库。所以 onSensorChanged
方法既写入数组,又从数组读取数据写入数据库
我的问题是,onSensorChanged
方法是否应该同步?
最重要的是我不会错过任何数据。我需要每 10 毫秒存储一次当前传感器值 - 不能遗漏任何一个。
据我了解,同步方法意味着 UI 线程将持有锁,并将传感器值写入数组。在此期间,由于锁定,执行程序线程无法从这些数组中读取。然后解除锁,执行线程加锁,读取数组,写入数据库,释放锁
我可能误解了这里同步方法的使用,特别是考虑到 onSensorChanged
是事件驱动的,我不确定它是如何发挥作用的
但似乎在这种情况下,我可能不会每 10 毫秒插入一次最新值。当 UI 线程建立锁时,执行线程不能将这些值写入数据库。到执行程序线程可以写入时,这些值现在已经有几毫秒了并且不准确
另一方面,同步意味着我不会遇到 UI 线程正在更改数组值,同时执行程序线程将一半更改的值插入数据库的情况
那么对于这种我需要每 10 毫秒插入最新/准确的传感器数据的情况,我应该使用同步方法吗?
最佳答案
您当前的代码不是线程安全的,因为 Runnable
使用的是 UI 线程正在写入的相同数组。一旦您调用 executor.execute(insertHandler);
就无法保证 UI 线程不会获得另一个传感器事件并在 Runnable
写入它们之前更改其中一个数组值到数据库。看来你明白这部分了。
要解决此问题,我根本不建议使用同步块(synchronized block),因为看起来您只想在 diffTime > POLL_FREQUENCY
时写出存储在数组中的任何值。 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
添加到 executor
时使用:
Runnable insertHandler = new InsertHandler(accelerometerMatrix, accelerometerWorldMatrix,
gyroscopeMatrix, gravityMatrix, magneticMatrix, rotationMatrix);
executor.execute(insertHandler);
关于java - Android 同步 onSensorChanged?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36400283/
这是我的职责。 public void onSensorChanged(SensorEvent event) { if (event.sensor.getType()
我有以下函数来监听加速度计和磁力计值: // Storage for Sensor readings public float[] mGravity = new float[3]; pub
我昨天刚开始使用 android 和 java,但遇到了问题。我正在尝试将传感器的值输出到某些 TextView。文本更新,但使用定义时设置的值。 onSensorChanged 应该更新这些值吗?
我正在开发一个可穿戴应用程序,我注意到一个奇怪的行为。我有一个类 FooService extends Service implements SensorEventListener 并且我重写了 on
我有一个 SensorEventListener,它在 onSensorChanged() 方法中执行如下操作: public void onSensorChanged(SensorEvent e){
我试图在 1 秒内获得 100 个加速度计读数,但它不是 100 个不同的读数,而是 100 次给出 1 个相同的读数。 当我按下应用程序中的按钮时,我尝试显示这 100 个加速度计读数 我的 Mai
我读过一些关于哪个线程调用各种回调方法的讨论,例如与传感器关联的回调方法。大多数声称 UI 线程调用回调 - 即使涉及单独的工作线程。我们确定吗? 考虑这种情况:一个单独的类实现 Runnable 和
今晚我在传感器方面遇到了很多麻烦,但似乎是因为没有调用 onSensorChanged()。很抱歉最终出现重复问题,但我没有看到任何解决方案。这是我的代码: public SensorManager
我正在编写 Android 应用程序,但在使用加速度计时遇到了一些问题。奇怪的是,我的函数 onSensorChanged() 没有被调用,我不知道为什么:/你能帮帮我吗? :) 这是我的代码: @S
我正在尝试开发一个检测跌倒的应用程序,到目前为止,跌倒的准确性在可接受的范围内,但问题是“OnSensorChanged”的调用过于频繁,导致 toast 不断出现在我的屏幕上. 我认为问题在于,在自
我需要在另一种方法中使用传感器的值。我不知道如何从 onSensorChanged() 方法获取值。 我尝试创建一个全局字段,在其中写入传感器值,但在 onSensorChanged() 方法之外该字
当我使用onSensorChanged()测试手机的加速度计时,发现它响应速度很快。几乎每1~3msonSensorChanged()就会被激活。我查了一些其他手机的信息,感觉有点奇怪,所以我怀疑我的
我是 Android 开发新手。我正在构建一个简单的 Android 应用程序,它分析加速计传感器数据并使用 MediaPlayer 播放声音。 SensorEventListener 实现代码:
当传感器打开时,onSensorChanged 上有数据 连续。 我想: 开启传感器 10 秒,每隔 10 秒读取一次数据。 关闭传感器 20 秒。 不断重复同一件事(步骤 1 到 2)。 我使用 S
我已经编写了一种通过网络发送 UDP 消息的方法。它工作正常。 在那之后,我尝试使用我的 Galaxy S 智能手机的加速计传感器。我得到了加速计值,并将它们显示在屏幕上。当值发生变化时(onSens
我将传感器用作 Sensor.TYPE_ACCELEROMETER。我正在按如下方式实现 OnSensorChanged() 方法: @Override public void onS
我正在使用传感器加速度计,我想知道它是否可能以及如何在 onSensorChanged 中运行两个东西。1. 我想将加速度计数据 x、y、z 始终存储在现场2. 如果检测到抖动,运行另一个 Activ
这是我的问题的后续:Android thread runnable performance 我在思考应用程序的同步方法时遇到了一些困难 我轮询传感器并在传感器值发生变化时将其存储到数组中 float[
只是想知道,有没有办法在 Android 手机上获取光传感器的值,而无需等待 onSensorChanged() 事件发生?为了节省电量,我在获得单个 lux 值后使用 registerListene
我需要检查移动设备是否处于水平位置(没有横向,我的意思是就像你把它放在 table 上一样)。 我知道我必须使用“SensorEventListener”接口(interface)和“onSensor
我是一名优秀的程序员,十分优秀!