Reputation: 93
I have a simple Android app, which is supposed to get several readings from a sensor at a certain time interval.
I currently have two threads:
UI thread that initiates the sequence (via a message to a worker thread handler), and also keeps track of its state (whether I am doing the first measurement, or a repeated measurement).
A worker thread, which runs in a background and communicates with the main thread via main thread handler.
My intent is to keep all the logic about when to do the measurements within the main UI thread (those are simple number comparisons, and no time consuming work, so should be suitable for UI thread), and set up a worker thread as a thread that only knows how to respond to a request to read data from sensor and return the result of such reading.
My issue is in this worker thread. It receives a request to do a measurement via a message, and handles this request in its handleMessage method:
public boolean handleMessage(Message msg) {
if (msg.what == StartMeasurementCmd) {
Log.d(TAG, "Starting measurement");
// register sensor event listener
// wait for onSensorChanged
// unregister sensor event listener
Log.d(TAG, "Measurement finished");
// Notify UI thread via uiHandler
Message newMsg = uiHandler.obtainMessage();
newMsg.what = DoneMeasurementCmd;
// add whatever information is needed to the newMsg
newMsg.setTarget(uiHandler);
newMsg.sendToTarget();
}
return false;
}
Here StartMeasurementCmd and DoneMeasurementCmd are simple constants.
Once worker thread receives the request to measure data, it needs to register a sensor listener (first comment line above), but then it needs to wait until the reading is available (second comment line above). After reading is available, it will unregister the listener (third comment line above), and send a message to UI thread to notify that new data is available. I can think of two ways to fill in the second comment line:
Android sensor registerListener in a separate thread
A method for waiting for sensor data
My question is - is there a way to get the reading within the same worker thread, but without doing a "busy" wait in while loop? Or is one of the above methods actually a recommended one?
Thanks!
Upvotes: 1
Views: 1229
Reputation: 3638
If i understand correctly, it is OK to block the worker thread. Then you don't need a separate thread, it would suffice to make the listener object a monitor (i.e. with synchronized
methods) and wait on that.
For instance, something along the lines of (with the handling of the actual data roughly sketched):
class ListenerMonitor implements WhateverListenerInterface {
private boolean gotData;
... some variable(s) to record the actual data
public synchronized void onSensorChanged(...) {
...
gotData=true;
notifyAll();
}
public synchronized SuitableReturnType readSensor(...) throws InterruptedException {
// register sensor event listener
gotData = false;
while(!gotData) wait();
// unregister sensor event listener
return the data?
}
}
and use it in the worker thread:
...
ListenerMonitor listenerMonitor = new ListenerMonitor(...);
...
public boolean handleMessage(Message msg) {
if (msg.what == StartMeasurementCmd) {
Log.d(TAG, "Starting measurement");
... = listenerMonitor.readSensor(...);
Log.d(TAG, "Measurement finished");
Upvotes: 0