Java 在Android中的onSensorChanged()中生成线程

Java 在Android中的onSensorChanged()中生成线程,java,android,multithreading,design-patterns,android-sensors,Java,Android,Multithreading,Design Patterns,Android Sensors,我正在制作一个应用程序,根据方向和加速度计读数跟踪运动(运动速度非常慢)。我拥有的是一种策略模式,一种情况,我有一个抽象的练习动作类,具体的练习动作实现实际的东西。问题是,我正在生成线程来跟踪活动中onSensorChanged()方法中的不同练习。由于这将被多次调用,我不知道我的代码是否会产生同样多的线程。他们把垃圾收集起来了吗 代码: 公共类WorkoutBuddy扩展活动实现SensorEventListener{ 文本视图t1、t2、t3、t4、t5、t6、t7; 传感器管理器传感器管理

我正在制作一个应用程序,根据方向和加速度计读数跟踪运动(运动速度非常慢)。我拥有的是一种策略模式,一种情况,我有一个抽象的练习动作类,具体的练习动作实现实际的东西。问题是,我正在生成线程来跟踪活动中onSensorChanged()方法中的不同练习。由于这将被多次调用,我不知道我的代码是否会产生同样多的线程。他们把垃圾收集起来了吗

代码:

公共类WorkoutBuddy扩展活动实现SensorEventListener{
文本视图t1、t2、t3、t4、t5、t6、t7;
传感器管理器传感器管理器;;
专用传感器;
专用传感器磁场;
私人浮动[]价值加速度计;
私人浮动[]价值磁场;
私人浮动[]价值定向;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.exercise_buddy);
sensorManager=(sensorManager)getSystemService(传感器服务);
SensorAccelerator=sensorManager.getDefaultSensor(传感器类型\加速计);
sensorMagneticField=sensorManager.getDefaultSensor(传感器类型\u磁场);
数值加速度计=新浮点数[3];
valuesMagneticField=新浮点数[3];
valuesOrientation=新浮动[3];
matrixR=新浮动[9];
matrixI=新浮动[9];
matrixValues=新浮点数[3];
//mediaPlayer=mediaPlayer.create(这是R.raw.first\u position\u confirmation);
}
@凌驾
受保护的void onPause(){
sensorManager.UnregistereListener(此为SensorAccelerator);
sensorManager.UnregistereListener(此为sensorMagneticField);
super.onPause();
}
@凌驾
精度更改时的公共无效(传感器,int精度){
//TODO自动生成的方法存根
}
浮动[]方向;
私人浮动[]矩阵;
私人股本;第十一条;
私有浮动[]矩阵值;
@凌驾
传感器更改时的公共无效(传感器事件){
if(event.sensor.getType()==sensor.TYPE\u加速计){
valuesAccelerometer=低通(event.values.clone(),valuesAccelerometer);
}else if(event.sensor.getType()==sensor.TYPE\u磁场){
valuesMagneticField=低通(event.values.clone(),valuesMagneticField);
}
if(valuesAccelerometer!=null&&valuesMagneticField!=null){
SensorManager.getRotationMatrix(矩阵X、矩阵XI、值加速度计、值磁场);
如果(真){
SensorManager.getOrientation(matrixR、matrixValues);
双方位角=数学toDegrees(矩阵值[0]);
双节距=数学toDegrees(matrixValues[1]);
双辊=数学toDegrees(matrixValues[2]);
参数方向[0]=(浮动)节距;
参数方向[1]=(浮动)滚动;
值方位[0]=(浮动)方位角;
Thread forExc1=新线程(新的左肩(valuesAccelerometer,valuesOrientation,this));
Thread forExc2=新螺纹(新右肩(值加速度计、值方向,此));
forExc1.run();
forExc2.run();
}
}
}
@凌驾
受保护的void onResume(){
sensorManager.registerListener(这是传感器加速计,传感器管理器,传感器延迟正常);
sensorManager.registerListener(此,传感器磁场,传感器管理器,传感器延迟正常);
super.onResume();
}
//用于平滑传感器读数的低通滤波器
受保护的浮点[]低通(浮点[]输入,浮点[]输出){
浮动α=0.25f;
if(output==null)返回输入;
对于(int i=0;i-10&&acc[0]<-8.5&&!播放){
mediaPlayer.start();
播放=真实;
}
}
}

如果您只是覆盖SensorChanged上的
并输出
Log.d
,您将看到它被称为每秒数百次,甚至数千次

我建议您使用相反的方法:只创建一个线程,在后台处理不同的接收事件,然后从onSensorChanged提供这样的线程

在线程中实现某种类型的事件队列。假设成千上万的事件会不断地到来

比如:

        private class ShoulderMovementProcessorThread extends Thread {

               .....

               // this will be called from the UI thread, just add event to the (synchronized) queue.

               public void publish (int[] valuesAccelerometer, int[] valuesWhatever) {

                     add_event_to_queue();

               }

               // this is the typical event loop where you read one from the queue, process it, then wait for the next
               public void run() {
                   -> get event
                   -> process event
                   -> wait for next event
               }

        }

        ShoulderMovementProcessorThread mShoulderProcessor=new ShoulderMovementProcessorThread(...);

        @Override
        public void onSensorChanged(SensorEvent event) {
              decodeEvent (event); // fills up azimuth, roll, etc.
              mShoulderProcessor.publish(valuesAccelerometer, valuesWhatever);           

        }


        // decode an event
        private void decodeEvent (SensorEvent event) {

            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                valuesAccelerometer = lowPass(event.values.clone(), valuesAccelerometer);
            } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
                valuesMagneticField = lowPass(event.values.clone(), valuesMagneticField);
            }
            if (valuesAccelerometer != null && valuesMagneticField != null) {
                SensorManager.getRotationMatrix(matrixR, matrixI, valuesAccelerometer, valuesMagneticField);

                if(true){
                    SensorManager.getOrientation(matrixR, matrixValues);

                    double azimuth = Math.toDegrees(matrixValues[0]);
                    double pitch = Math.toDegrees(matrixValues[1]);
                    double roll = Math.toDegrees(matrixValues[2]);

                    valuesOrientation[0]=(float) pitch;
                    valuesOrientation[1]=(float) roll;
                    valuesOrientation[0]=(float) azimuth;

                }

            }
        }

我最近实现了类似的功能:

public class DBWorkerThread implements Runnable
{
    private  SensorEnum sensorType;
    private LinkedBlockingQueue<float[]> sensorData;
    private DBService dbService;

    public DBWorkerThread(SensorEnum type, DBService dbService)
    {
        this.sensorType = type;
        this.dbService = dbService;
        this.sensorData = new LinkedBlockingQueue<float[]>();
    }

    /**
     * Add data to queue
     * @param values
     */
    public void addDataToProcess(float[] values)
    {
        if (sensorData.size() < sensorData.remainingCapacity())
        {
            try
            {
                this.sensorData.put(values);
            }
            catch (Exception ex)
            {
                LogService.log("Error adding queue: " + ex.getMessage());
            }
            LogService.log("Added to queue. Size: " + sensorData.size());
        }
    }

    /**
     * Processes queue of data
     */
    @Override
    public void run()
    {
        // Moves the current Thread into the background
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

        while (sensorData.size() > 0)
        {
            try
            {
                float[] values = sensorData.take();
                storeData(values);
            }
            catch (Exception ex)
            {
                LogService.log("Error in queue: " + ex.getMessage());
            }
        }
    }

    /**
     * Store data to database
     * @param values
     */
    private void storeData(float[] values)
    {
        // store data
    }
}
公共类DBWorkerThread实现可运行
{
私有SensorEnum sensorType;
私有链接锁定队列传感器数据;
专用数据库服务;
公共DBWorkerThread(SensorEnum类型,DBService DBService)
{
这一点。传感器类型=类型;
this.dbService=dbService;
this.sensorData=new LinkedBlockingQueue();
}
/**
*将数据添加到队列
*@param值
*/
public void addDataToProcess(float[]值)
{
if(sensorData.size()0)
{
尝试
{
float[]value=sensorData.take();
存储数据(值);
}
捕获(例外情况除外)
{
日志
public class DBWorkerThread implements Runnable
{
    private  SensorEnum sensorType;
    private LinkedBlockingQueue<float[]> sensorData;
    private DBService dbService;

    public DBWorkerThread(SensorEnum type, DBService dbService)
    {
        this.sensorType = type;
        this.dbService = dbService;
        this.sensorData = new LinkedBlockingQueue<float[]>();
    }

    /**
     * Add data to queue
     * @param values
     */
    public void addDataToProcess(float[] values)
    {
        if (sensorData.size() < sensorData.remainingCapacity())
        {
            try
            {
                this.sensorData.put(values);
            }
            catch (Exception ex)
            {
                LogService.log("Error adding queue: " + ex.getMessage());
            }
            LogService.log("Added to queue. Size: " + sensorData.size());
        }
    }

    /**
     * Processes queue of data
     */
    @Override
    public void run()
    {
        // Moves the current Thread into the background
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

        while (sensorData.size() > 0)
        {
            try
            {
                float[] values = sensorData.take();
                storeData(values);
            }
            catch (Exception ex)
            {
                LogService.log("Error in queue: " + ex.getMessage());
            }
        }
    }

    /**
     * Store data to database
     * @param values
     */
    private void storeData(float[] values)
    {
        // store data
    }
}