tags:

views:

38

answers:

1

This seems like a basic question, but after searching for a while and playing with it, I've come to the point where some help would be appreciated. I would like to have a SensorEventListener run in a separate thread from the UI, so that computations that need to occur when events come in won't slow down the UI.

My latest attempt looks like:

class SensorThread extends Thread {
    SensorManager mSensorManager;
    Sensor mSensor;

    public void run() {
        Log.d( "RunTag", Thread.currentThread().getName() ); // To display thread
        mSensorManager = (SensorManager)getSystemService( SENSOR_SERVICE  );
        mSensor = mSensorManager.getDefaultSensor( Sensor.TYPE_ACCELEROMETER );
        MySensorListener msl = new MySensorListener();
        mSensorManager.registerListener(msl, mSensor, SensorManager.SENSOR_DELAY_UI );
    }

    private class MySensorListener implements SensorEventListener {
        public void onAccuracyChanged (Sensor sensor, int accuracy) {}
        public void onSensorChanged(SensorEvent sensorEvent) {
            Log.d( "ListenerTag", Thread.currentThread().getName() ); // To display thread
        }
    }

In the activity's (or service's) onCreate(), I create a SensorThread object and call its start() method. As you would expect, the debug log shows the "RunTag" entry in the new thread. But onSensorChanged()'s "ListenerTag" is running in the main thread, even though its object is instantiated in the new thread. How do I change that?

A: 

It looks like the SensorManager is actually responsible for calling the onSensorChanged method, and I don't think the fact that registerListener is called in this separate thread is going to make any difference. The easiest thing to do is probably to make onSensorChanged return instantly, by delegating all the heavy lifting to a separate thread. Or perhaps to an ASyncTask, which seems to be the official "right way" of doing such things.

MatrixFrog
Thanks for the idea. I come from the 8-bit micro world, so I may need to adjust my thinking some. Allocating new tasks every time the sensor changes (5-50x a second, depending on sample rate) seems like a waste.
Thinman
Well, maybe it would only allocate the task in certain cases. For example, maybe it stores the sensor reading in memory, and then checks in the onSensorChanged method whether the reading has changed more than some threshold. If it has, THEN it starts up the ASyncTask. I'm really just getting started with Android though, so I don't really know what will work best.
MatrixFrog