java - 我的传感器监控技术有什么问题?

标签 java android android-sensors orientation-changes blockingqueue

(请阅读最后的更新 3)我正在开发一个持续与设备传感器配合使用的应用程序,与 AccelerometerMagnetic 传感器配合使用以检索设备方向(目的已提及 here )。换句话说,我的应用程序需要实时了解设备的方向(但这永远不可能,所以要尽可能快,但要尽可能快 可能 !)。正如 Reto Meier 在 professional Android 4 Application Development 中提到的:

The accelerometers can update hundreds of times a second...

我不能丢失传感器报告的任何数据,我还想对这些数据进行耗时的操作(检索方向然后进行计算...)。我决定使用 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();
        }
    });
}

    public void doCalculations() {
    for (;;) {
        float[][] result = null;
        try {
            result = array.take();
        } catch (InterruptedException e) {
        }
        float[] aValues, mValues;
        aValues = result[0];
        mValues = result[1];

                    int[] degrees=getOrientation(aValues,mValues);
                    Log.e("",String.valueOf(degrees[0]));

                 //other calculations...
                     }
                                }

现在我拿起​​我的设备并将其向右旋转约 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:我更新了 doCalculations() 方法以更加清楚我做了什么

UPDATE 3: I think maybe we can solve the problem in another way! I have clear purposes for this code. please have a look at this. I have mentioned what is going to happen, I need to detect an specific movement gesture. so maybe the whole way that I have chosen(the technique above) is not a good way for solving this problem. maybe it's better to detect that gesture by using other sensors or using the same sensors in other way. what do you think?

最佳答案

看来您正在尝试为标准“生产者-消费者”问题寻找高吞吐量、低延迟的解决方案。基本上这个想法非常简单:减少数据处理开销,并行处理数据。建议如下:

<强>1。使用“低延迟”库

  • javolution.org - 是一个实时库,旨在使 Java 或 Java-Like/C++ 应用程序更快,时间更可预测。它包括 Android 支持。
  • mentaqueue - 是一个基于 Disruptor 思想的超快、无垃圾、无锁、双线程(生产者-消费者)队列。 Android 支持未定义(看起来应该可以)。
  • disruptor - 又一个快如闪电的图书馆
  • trove - 为 Java 提供高速常规和原始集合。

任何这些解决方案都会让您节省大量的 CPU 周期。

enter image description here

<强>2。明智地处理数据

每次提交作业都会产生开销。批处理真的很有用。

enter image description here

连续处理数据。注意,executor.execute 会消耗很多。几个长寿的消费者可能会有所帮助。

<强>3。最后,使用微优化技术

例如,摆脱 if-else-if 以支持 switch

始终跟踪性能,以确定好的和坏的解决方案。实验。

快乐编码。

关于java - 我的传感器监控技术有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18786694/

相关文章:

android - 在 Android 应用程序中重新映射坐标系

java - 如何将字符数组与 boolean 值进行比较

java - 为什么字符串中有逗号时 JSON 无效?

java - JVM 未退出

android - 如何同时使用新的Android 2.0 Shrinker 和Resource Shrinker?

java - 如何在 Android/Java 中同步 File 对象

java - SMS Retriever API 中发布的 APK 上的 HASH 字符串 key

android - 我应该使用什么来托管视频以在我的移动应用程序中进行流式传输

android - 如何将 Android 传感器的数据写入我以后可以访问的文档?

android - 如何从传感器确定设备方向