Java 在Android中的onSensorChanged()中生成线程
我正在制作一个应用程序,根据方向和加速度计读数跟踪运动(运动速度非常慢)。我拥有的是一种策略模式,一种情况,我有一个抽象的练习动作类,具体的练习动作实现实际的东西。问题是,我正在生成线程来跟踪活动中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; 传感器管理器传感器管理
公共类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
}
}