I have an application in Android that dumps the sensor values to the SDcard memory of the phone and kills itself when I press a button on the screen. I am using Sensor_delay_fastest to get maximum update of the sensors.
My problem is that since I'm doing all my computation on the UI thread, the button takes very long to respond, which is very bad for my application as it records all the extra values after I press the Kill button. I understand that I should put my computations in another thread, but I'm not sure how I would do that for event handling operations. For instance, I have
protected void onResume()
{
super.onResume();
sm.registerListene开发者_如何学Gor(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_FASTEST);
}
and onStop(), and the functions onSensorChanged() and onAccuracyChanged(), which are executed when the event fires. Actually, the main 'heavy' computation is in my onSensorChanged(), where I write the values on the SDcard, which is probably causing the delay. But I can't put it in a different thread because then it'll create a LOT of threads as the events keep firing.
So how do I make this system more responsive? I'm really new to Android, and some help by means of some sample code will be greatly appreciated.
Thanks all!
EDIT: Can I make a thread implement an interface, like SensorEventListener and then implmeent OnResume and OnStop within that thread?
I like to get the sensors in a different Thread, too. For this purpose I created a HandlerThread while passing a Context for the Managers:
public class SensorDataThread extends HandlerThread implements Handler.Callback{
private Handler mThreadHandler;
private SensorManager mSensorManager;
private SensorDataThread(Context ctx) {
super("SensorDataThread", android.os.Process.THREAD_PRIORITY_BACKGROUND);
mSensorManager = (SensorManager)ctx.getSystemService(Context.SENSOR_SERVICE);
}
public synchronized void start(){
super.start();
mThreadHandler = new Handler(getLooper(), this);
}
public boolean handleMessage(Message msg)...
}
then I register a Handler Object on its Looper after starting it:
SensorDataThread sdt = new SensorDataThread(this);
sdt.start():
from this point we have a new Thread which we can send Messages through its Handler.
the trick is now to use the SensorManager.registerListener() with a Handler Object in which the data is computed.
mSensorManager.registerListener([listener], [type], [delay], mThreadHandler);
from that Interface (which can be implemented by SensorThread itself) you just pass the SensorEvents or whatever to the ThreadHandler.
public void onSensorChanged(SensorEvent event) {
mThreadHandler.obtainMessage(MSG_SENSOR_EVENT, event)
.sendToTarget();
}
be shure you either unregister the Listeners or stop the Thread by calling sdt.quit() otherwise it will drain your battery empty.
You could queue up a bunch of sensor changes in memory and then only write to the sd card when you reach a certain amount of data or the user pushes the button. Reducing the number of times you write to the SD Card would probably make it much more responsive.
精彩评论