I'm implementing a series of characteristic reads against a BLE device. Because readCharacteristic() executes asynchronously, and because we have to wait until it completes before issuing another "read" call, I used a lock to wait() and then in 'onCharacteristicRead() I notify() the lock to get things going again.
When I wait() after calling readCharacteristic(), I never get a call to onCharacteristicRead(). If I don't wait(), then I do get a call to onCharacteristicRead() and the correct value is reported.
Here is the relevant code that seems to block the callback to onCharacteristicRead():
private void doRead() {
//....internal accounting stuff up here....
characteristic = mGatt.getService(mCurrServiceUUID).getCharacteristic(mCurrCharacteristicUUID);
isReading = mGatt.readCharacteristic(characteristic);
showToast("Is reading in progress? " + isReading);
showToast("On thread: " + Thread.currentThread().getName());
// Wait for read to complete before continuing.
while (isReading) {
synchronized (readLock) {
try {
readLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
showToast("onCharacteristicRead()");
showToast("On thread: " + Thread.currentThread().getName());
byte[] value = characteristic.getValue();
StringBuilder sb = new StringBuilder();
for (byte b : value) {
sb.append(String.format("%02X", b));
}
showToast("Read characteristic value: " + sb.toString());
synchronized (readLock) {
isReading = false;
readLock.notifyAll();
}
}
If I simply remove the while() statement above, I successfully get the read callback. Of course, that prevents me from waiting to do further reads, so I can't move forward without waiting.
Given that the readCharacteristic() is asynchronous, why would execution of the calling thread have anything to do with the ability to actually do the read, or the ability to call the callback?
To make things more confusing, I show a toast which identifies the thread when I call readCharacteristic(), as well as when onCharacteristicRead() is invoked. These 2 threads have different names. I thought that maybe the callback was being invoked on the calling thread for some reason, but that doesn't appear to be the case. So what is going on here with the threading?