Java 什么';我的传感器监控技术有什么问题?
(请阅读结尾处的更新3)我正在开发一个应用程序,它可以与设备的传感器持续工作,与Java 什么';我的传感器监控技术有什么问题?,java,android,android-sensors,orientation-changes,blockingqueue,Java,Android,Android Sensors,Orientation Changes,Blockingqueue,(请阅读结尾处的更新3)我正在开发一个应用程序,它可以与设备的传感器持续工作,与加速计和磁性传感器一起工作,以检索设备的方向(目的已提及)。换句话说,我的应用程序需要实时知道设备的方向(但这是不可能的,所以尽可能快,但真正尽可能快)。正如Reto Meier在专业Android 4应用程序开发中提到的: 加速度计每秒可以更新数百次 我不能丢失传感器报告的任何数据,我还想对这些数据执行耗时的操作(检索方向,然后进行计算…)。我决定使用LinkedBlockingQueue解决我的问题: p
加速计
和磁性
传感器一起工作,以检索设备的方向(目的已提及)。换句话说,我的应用程序需要实时知道设备的方向(但这是不可能的,所以尽可能快,但真正尽可能快)。正如Reto Meier在专业Android 4应用程序开发中提到的:
加速度计每秒可以更新数百次
我不能丢失传感器报告的任何数据,我还想对这些数据执行耗时的操作(检索方向,然后进行计算…)。我决定使用LinkedBlockingQueue
解决我的问题:
public void startSensors() {
LinkedBlockingQueue<float[][]> array=new LinkedBlockingQueue();
sensorListenerForOrientation = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
aValues = (event.values.clone());
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mValues = (event.values.clone());
if (aValues != null && mValues != null) {
try {
array.put(new float[][] { aValues, mValues });
} catch (InterruptedException e) {
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(
sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1);
Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(
sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1);
sm.registerListener(sensorListenerForOrientation, aSensor,
SensorManager.SENSOR_DELAY_FASTEST);
sm.registerListener(sensorListenerForOrientation, mSensor,
SensorManager.SENSOR_DELAY_FASTEST);
executor.execute(new Runnable() {
@Override
public void run() {
doCalculations();
}
});
}
现在我拿起我的设备,将其向右旋转90度,然后快速返回到第一个位置(例如1.5秒),但当我查看设备中注册的方向时,我看到例如:0,1,2,3,4,5……,40,39,38,37……,0
我只想说,我在我的结果中看不到很大的学位范围。
根据我所做的和我所研究的我可以确保我没有丢失任何数据,传感器报告的任何新数据都会被记录下来
有什么想法,解决办法吗
问候
更新1:我用我的设备做了另一个实验,得到了令人震惊的结果!如果我将设备在轴上快速旋转90度(不到一秒),我可以看到结果中的所有度:0,1,2,3,…,89,90(例如),但如果我将其旋转90度,然后将其旋转回第一个位置,结果将是0,1,2,…,36,37,36,…,2,1,0(例如)…真令人困惑
更新2:我更新了doccalculations()方法,以便更清楚地了解我所做的工作
更新3:我想也许我们可以用另一种方式解决这个问题!我对这一准则有明确的目的。请看一看。我
我已经提到将要发生什么,我需要检测一个特定的
动作手势。因此,也许我选择的整个方式
上述技术)不是解决此问题的好方法。大概
最好使用其他传感器或使用
同样的传感器在另一方面。你觉得怎么样?
List array=Collections.synchronizedList(新的ArrayList());
Iterator values=array.Iterator();
while(values.hasNext()){
float[][]结果=值。下一步();
//算计。
//计算完毕后,删除项目。
value.remove();
}
因此,看起来您正试图为标准的“生产者-消费者”问题找到高吞吐量、低延迟的解决方案。基本上,这个想法非常简单:减少数据处理开销,并行处理数据。建议如下:
public void startSensors() {
final Stack<Runnable> mStack = new Stack<Runnable>();
sensorListenerForOrientation = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
aValues = (event.values.clone());
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mValues = (event.values.clone());
if (aValues != null && mValues != null) {
mStack.push(new Calculater(new float[][] { aValues, mValues });
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(
sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1);
Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(
sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1);
sm.registerListener(sensorListenerForOrientation, aSensor,
SensorManager.SENSOR_DELAY_FASTEST);
sm.registerListener(sensorListenerForOrientation, mSensor,
SensorManager.SENSOR_DELAY_FASTEST);
new Thread() {
public void run() {
while(true)
{
try {
Runnable r = mStack.pop();
r.run();
} catch(Exception ex){}
}
}
}.start();
}
private class Calculater implements Runnable {
float[][] theValues;
public Calculater(float[][] values) {
theValues = values;
}
public void run() {
int[] degrees= getOrientation(theValues[0], theValues[1]);
Log.e("",String.valueOf(degrees[0]));
}
}
1。使用“低延迟”库
- -是一个实时库,旨在使Java或类似Java的/C++应用程序更快、时间更可预测。它包括Android支持
- -是基于破坏者思想的超快速、无垃圾、无锁、双线程(生产者-消费者)队列。Android支持尚未定义(看起来应该可以工作)
- -又一个闪电图书馆
- -为Java提供高速常规和基本集合李>
executor.execute
将消耗大量资源。一些长寿消费者可能会有所帮助
3。最后,使用微观优化技术
例如,去掉if-else-if
,选择开关
始终跟踪性能,以确定好的和坏的解决方案。实验
快乐编码。只是想一想:请尝试以下方法:
public void startSensors() {
final Stack<Runnable> mStack = new Stack<Runnable>();
sensorListenerForOrientation = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
aValues = (event.values.clone());
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mValues = (event.values.clone());
if (aValues != null && mValues != null) {
mStack.push(new Calculater(new float[][] { aValues, mValues });
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(
sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1);
Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(
sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1);
sm.registerListener(sensorListenerForOrientation, aSensor,
SensorManager.SENSOR_DELAY_FASTEST);
sm.registerListener(sensorListenerForOrientation, mSensor,
SensorManager.SENSOR_DELAY_FASTEST);
new Thread() {
public void run() {
while(true)
{
try {
Runnable r = mStack.pop();
r.run();
} catch(Exception ex){}
}
}
}.start();
}
private class Calculater implements Runnable {
float[][] theValues;
public Calculater(float[][] values) {
theValues = values;
}
public void run() {
int[] degrees= getOrientation(theValues[0], theValues[1]);
Log.e("",String.valueOf(degrees[0]));
}
}
public void startSensors(){
最终堆栈mStack=新堆栈();
sensorListenerForOrientation=新的SensorEventListener(){
@凌驾
传感器更改时的公共无效(传感器事件){
if(event.sensor.getType()==sensor.TYPE\u加速计)
aValues=(event.values.clone());
else if(event.sensor.getType()==sensor.TYPE\u磁场)
mValues=(event.values.clone());
if(aValues!=null&&mValues!=null){
mStack.push(新计算器(新浮点[][{aValues,mValues});
}
}
@凌驾
精度更改时的公共无效(传感器,int精度){
}
};
传感器A传感器=sm.getSensorList(传感器类型\加速计)。获取(
sm.getSensorList(传感器类型\加速计).size()-1);
传感器MSSensor=sm.getSensorList(传感器类型\u磁场)。获取(
sm.getSensorList(传感器类型\磁场).size()-1);
sm.寄存器侦听器(方向传感器侦听器、传感器、,
传感器管理器。传感器延迟(最快);
sm.寄存器侦听器(传感器侦听器用于定向,M传感器,
传感器管理器。传感器延迟(最快);
新线程(){
公开募捐{
while(true)
{
试试{
Runnable r=mStack.pop();
r、 run();
}捕获(例外情况除外){}
}
}
}.start();
}
私有类计算器实现可运行{
浮动[][]值;
公共计算器(浮点[][]值){
价值=价值;
}
公开募捐{
int[]度=获取方向(值[
Iterator<float[][]> values = array.iterator();
while (values.hasNext()) {
float[][] result = values.next();
//calculating.
//after calculating remove the items.
values.remove();
}
public void startSensors() {
final Stack<Runnable> mStack = new Stack<Runnable>();
sensorListenerForOrientation = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
aValues = (event.values.clone());
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mValues = (event.values.clone());
if (aValues != null && mValues != null) {
mStack.push(new Calculater(new float[][] { aValues, mValues });
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Sensor aSensor = sm.getSensorList(Sensor.TYPE_ACCELEROMETER).get(
sm.getSensorList(Sensor.TYPE_ACCELEROMETER).size() - 1);
Sensor mSensor = sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).get(
sm.getSensorList(Sensor.TYPE_MAGNETIC_FIELD).size() - 1);
sm.registerListener(sensorListenerForOrientation, aSensor,
SensorManager.SENSOR_DELAY_FASTEST);
sm.registerListener(sensorListenerForOrientation, mSensor,
SensorManager.SENSOR_DELAY_FASTEST);
new Thread() {
public void run() {
while(true)
{
try {
Runnable r = mStack.pop();
r.run();
} catch(Exception ex){}
}
}
}.start();
}
private class Calculater implements Runnable {
float[][] theValues;
public Calculater(float[][] values) {
theValues = values;
}
public void run() {
int[] degrees= getOrientation(theValues[0], theValues[1]);
Log.e("",String.valueOf(degrees[0]));
}
}
@Override
public void onSensorChanged(SensorEvent event) {
int i = event.sensor.getType();
if (i == Sensor.TYPE_ACCELEROMETER)
aValues = (event.values.clone());
else if (i == Sensor.TYPE_MAGNETIC_FIELD)
mValues = (event.values.clone());
}
@Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float acceleration = FloatMath.sqrt((x * x) + (y * y) + (z * z));