2

I am using a ScheduledExecutorService to run a Runnable periodically. In the Runnable I have registered a SensorEventListener. I noticed that the SensorEventListener callbacks gets called on the main thread rather than a thread from the thread pool of the ScheduledExecutorService. I want to handle the callbacks for the sensor events off of the main thread. It looks like I am able to pass a Handler object when calling registerListener() of the SensorManager class and the callbacks will be run on the thread that the Handler is from.

Is there a way to get a reference to a Handler of a ScheduledExecutorService?

neonDion
  • 2,278
  • 2
  • 20
  • 39

3 Answers3

5

It's hard. A regular ExecutorService does not have a Looper and you can not have a Handler in such a thread.

A Looper is an infinite loop that dequeues and executes events. So if you schedule that your executor is blocked. You can probably implement your own executor based on the event handling of a Looper but I guess that's not what you want.

To use the sensor from the background you would create a HandlerThread. That's a background thread running a Looper and therefore it can have a Handler.

Small example

private HandlerThread mHandlerThread;
private Handler mBackgroundHandler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mHandlerThread = new HandlerThread("SomeNameHere");
    mHandlerThread.start();
    mBackgroundHandler = new Handler(mHandlerThread.getLooper());

    mBackgroundHandler.post(new Runnable() {
        @Override
        public void run() {
            // I can do blocking network here.
        }
    });
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mHandlerThread.quitSafely();
}
zapl
  • 63,179
  • 10
  • 123
  • 154
  • 1
    Ok, that's what I ended up doing. Every 10 seconds I want to record 2 seconds worth of samples for SensorEvenListener. I ended up making a HandlerThread and getting a ref. to its Handler and passing that into SensorManager during registration. That HandlerThread then receives callback events and adds the values to a list. I kept my Scheduled ExecutorService which every 10 seconds runs a runnable that registers for sensor events, sleeps for 2 seconds (during this time the HandlerThread queues up values) then wakes up an unregisters for sensor events and caches values in db. Thanks! – neonDion Sep 21 '15 at 20:40
0

You can try Handler handler = new Handler(Looper.myLooper()); in the background thread (Where your ScheduledExecutorService is running) and then pass the instance to the SensorManager.

hoomi
  • 1,882
  • 2
  • 16
  • 17
0

Handler always 'handles' thing in the thread it was created, so just create a new one in your ExecutorService. Just use default Handler constructor

Gaskoin
  • 2,469
  • 13
  • 22
  • And then http://stackoverflow.com/questions/3875184/cant-create-handler-inside-thread-that-has-not-called-looper-prepare happens – zapl Sep 21 '15 at 20:25