Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/190.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';我的传感器监控技术有什么问题?_Java_Android_Android Sensors_Orientation Changes_Blockingqueue - Fatal编程技术网

Java 什么';我的传感器监控技术有什么问题?

Java 什么';我的传感器监控技术有什么问题?,java,android,android-sensors,orientation-changes,blockingqueue,Java,Android,Android Sensors,Orientation Changes,Blockingqueue,(请阅读结尾处的更新3)我正在开发一个应用程序,它可以与设备的传感器持续工作,与加速计和磁性传感器一起工作,以检索设备的方向(目的已提及)。换句话说,我的应用程序需要实时知道设备的方向(但这是不可能的,所以尽可能快,但真正尽可能快)。正如Reto Meier在专业Android 4应用程序开发中提到的: 加速度计每秒可以更新数百次 我不能丢失传感器报告的任何数据,我还想对这些数据执行耗时的操作(检索方向,然后进行计算…)。我决定使用LinkedBlockingQueue解决我的问题: p

(请阅读结尾处的更新3)我正在开发一个应用程序,它可以与设备的传感器持续工作,与
加速计
磁性
传感器一起工作,以检索设备的方向(目的已提及)。换句话说,我的应用程序需要实时知道设备的方向(但这是不可能的,所以尽可能快,但真正尽可能快)。正如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());
    
  • 在runnable内部:
  • 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提供高速常规和基本集合
    这些解决方案中的任何一个都可以让您节省大量的CPU周期

    2。明智地处理数据

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

    连续处理数据。注意,
    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));