我正在制作一个应用程序,它根据方向和加速度计读数跟踪锻炼 Action (锻炼 Action 非常慢)。我所拥有的是一种策略模式,在这种情况下,我有一个锻炼 Action 的抽象类,而具体的锻炼 Action 实现了实际的东西。问题是,我正在生成线程来跟踪 Activity 中 onSensorChanged() 方法中的不同练习。因为这将被调用很多次,所以我不知道我的代码是否会产生同样多的线程。他们会收集垃圾吗?
代码:
public class WorkoutBuddy extends Activity implements SensorEventListener {
TextView t1, t2, t3, t4, t5, t6, t7;
SensorManager sensorManager;;
private Sensor sensorAccelerometer;
private Sensor sensorMagneticField;
private float[] valuesAccelerometer;
private float[] valuesMagneticField;
private float[] valuesOrientation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.exercise_buddy);
sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
sensorAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorMagneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
valuesAccelerometer = new float[3];
valuesMagneticField = new float[3];
valuesOrientation = new float[3];
matrixR = new float[9];
matrixI = new float[9];
matrixValues = new float[3];
//mediaPlayer = MediaPlayer.create(this, R.raw.first_position_confirmation);
}
@Override
protected void onPause() {
sensorManager.unregisterListener(this,sensorAccelerometer);
sensorManager.unregisterListener(this,sensorMagneticField);
super.onPause();
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
float[] orientation;
private float[] matrixR;
private float[] matrixI;
private float[] matrixValues;
@Override
public void onSensorChanged(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;
Thread forExc1 = new Thread(new LeftShoulder(valuesAccelerometer, valuesOrientation, this));
Thread forExc2 = new Thread(new RightShoulder(valuesAccelerometer, valuesOrientation, this));
forExc1.run();
forExc2.run();
}
}
}
@Override
protected void onResume() {
sensorManager.registerListener(this,sensorAccelerometer,SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this,sensorMagneticField,SensorManager.SENSOR_DELAY_NORMAL);
super.onResume();
}
//Low pass filter used to smooth the sensor readings
protected float[] lowPass( float[] input, float[] output ) {
float ALPHA = 0.25f;
if ( output == null ) return input;
for ( int i=0; i<input.length; i++ ) {
output[i] = output[i] + ALPHA * (input[i] - output[i]);
}
return output;
}
}
package com.example.msapp2;
public abstract class ExerciseMovement implements Runnable{
protected float[] acc, ori;
protected boolean played = false;
}
package com.example.msapp2;
import android.content.Context;
import android.media.MediaPlayer;
public class LeftShoulder extends ExerciseMovement {
MediaPlayer mediaPlayer;
public LeftShoulder(float[] accelerometer, float[] orientation, Context context){
mediaPlayer = MediaPlayer.create(context, R.raw.first_position_confirmation);
acc = accelerometer;
//this.ori = orientation;
}
public void run(){
if(acc[0]> -10 && acc[0] < -8.5 && !played){
mediaPlayer.start();
played = true;
}
}
}
最佳答案
如果您只是覆盖 OnSensorChanged
并输出一个 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;
}
}
}
关于java - 在 Android 的 onSensorChanged() 中生成线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22725926/