我正在开发一个Android应用程序,它通过串行蓝牙将消息发送到响应的设备。
现在我面临的问题是方法依赖于其他方法。
例如,如果我按下应用程序中的开始按钮,则必须将用于开始测量的消息发送到硬件设备。但是,需要设备的当前设置(因此必须发送消息)。
现在的问题是,由于异步性,测量开始后我才收到设置(设置和测量开始的消息几乎同时发送)。由于正确的数据包处理需要进行设置,因此会导致错误的数据包处理。
为了说明问题,这是我当前(缩短的)代码:
public class DeviceManager {
// The current settings as single string value
private String deviceSettings = "";
// The last outgoing message
private String lastOutgoingMessage = "";
// The last incoming message
private String lastIncomingMessage = "";
// The measurement flag
private boolean isMeasurementOn = false;
// Local Bluetooth service
private BluetoothService bluetoothService = null;
// The Handler that gets information back from the BluetoothService
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// Construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
handleResponse(readMessage, readBuf);
break;
case Constants.MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// Construct a string from the buffer
String writeMessage = new String(writeBuf);
break;
}
}
};
/**
* Constructor
*/
public DeviceManager(BluetoothService bluetoothService) {
// Initialize Bluetooth service
this.bluetoothService = bluetoothService;
}
/**
* Handles the responses of the device.
*
* @param responseString String - The response as string
* @param responseArray byte[] - The response as bytes
*/
public void handleResponse(String responseString, byte[] responseArray) {
// Device settings requested
if (lastOutgoingMessage.equals("wbagds\r")) {
setDeviceSettings(responseString);
}
// Online measurement started (without sync)
if (lastOutgoingMessage.equals("wbaom7\r") && lastIncomingMessage.equals("wbav10\r")) {
// Set flag if not already set
if (!isMeasurementOn) {
isMeasurementOn = true;
}
}
// Data packet received
if (lastOutgoingMessage.equals("wbaom7\r") && isMeasurementOn) {
// Let create data packet
DataPacket dataPacket = dataPacketCreator.createDataPacket(responseArray, deviceSettings);
}
lastIncomingMessage = responseString;
}
/**
* Starts the online measurement by sending the appropriate string to the device (requests the device settings first).
*/
public void startOnlineMeasurement() {
// Device settings are needed first
requestDeviceSettings();
lastOutgoingMessage = "wbaom7\r";
sendMessageToDevice(lastOutgoingMessage);
}
/**
* Requests the device settings by sending the appropriate string to the device.
*/
public void requestDeviceSettings() {
lastOutgoingMessage = "wbagds\r";
sendMessageToDevice(lastOutgoingMessage);
}
}
我已经尝试过不同的方法,例如wait / notify,callable / future。
然而,我总是遇到一个问题,即我无法冻结线程,因为我不会收到并且无法再处理该消息,因此未来将永远不会被填满。
我如何管理此方法依赖项?我的申请中有任何明显的设计问题吗?线程有没有明显的解决方案?
答案 0 :(得分:2)
你应该改变你的设计。
当您还没有实际执行此操作的信息时,允许用户启动测量是没有意义的。
因此:你应该改变你的逻辑。首先查询以后需要的设置,并且仅在设置可用时才允许单击该按钮。
换句话说:只需避免两个异步调用重叠 - 确保“依赖”调用在第一个完成后发生!