Во многих местах я хочу, чтобы вызовы были синхронными, как в моем проекте Native.
Под синхронным имеется в виду что вызовы записи и чтения должны выполняться последовательно и что основной пользовательский интерфейс ждет, пока ответ от устройства не будет успешно прочитан, а затем продолжится выполнение.
Библиотеки, которые я использовал для последовательной связи раньше (в моем родном приложении), имели синхронные API и Я заметил, что почти все пакеты dart, выполняющие одну и ту же задачу (по сути, являются оболочками этих библиотек), предоставляют асинхронные API.
Чтобы добиться синхронного поведения, я сейчас делаю все функции которые используют мои базовые функции read и write, async и заставляют их возвращать подтип Future, а затем ожидать завершения всякий раз, когда необходимо.
Например: -
Вот некоторые из моих основных функций, реализованных в классе, который обрабатывает всю связь с использованием асинхронного API, предоставляемого пакетом dart usb_serial -
Код: Выделить всё
Future open() async {
if (!deviceFound) {
throw Exception("Device not connected");
}
mPort = await mDevice!.create();
bool openResult = await mPort!.open();
if (!openResult) {
throw Exception("Failed to open");
}
await mPort!.setPortParameters(
1000000,
UsbPort.DATABITS_8,
UsbPort.STOPBITS_1,
UsbPort.PARITY_NONE,
);
mPort!.inputStream!.listen((_) => ());
connected = true;
}
Future read(Uint8List dest, int bytesToRead, int timeoutMillis) async {
int numBytesRead = 0;
await for (Uint8List receivedData
in mPort!.inputStream!.timeout(Duration(milliseconds: timeoutMillis))) {
dest.setRange(0, receivedData.length, receivedData);
if (receivedData.length == bytesToRead) {
print("Read: $bytesToRead");
} else {
print("Read Error: ${bytesToRead - numBytesRead}");
}
return numBytesRead;
}
return numBytesRead;
}
Код: Выделить всё
Future _commonRead(int bytesToRead) async {
final List bytesRead = [0];
if (_mCommunicationHandler.isConnected()) {
bytesRead[0] =
await _mCommunicationHandler.read(_buffer, bytesToRead, _timeout);
}
return bytesRead[0];
}
Мой вопрос: нельзя ли каким-то образом сделать эти вызовы синхронными и избежать всего этого кода?
Что-то вроде моего собственного API (который использует синхронный API) -
Код: Выделить всё
public int read(byte[] dest, int bytesToBeRead, int timeoutMillis) throws IOException {
int numBytesRead = 0;
int readNow;
Log.v(TAG, "TO read : " + bytesToBeRead);
int bytesToBeReadTemp = bytesToBeRead;
while (numBytesRead < bytesToBeRead) {
readNow = port.read(mReadBuffer, bytesToBeReadTemp, timeoutMillis);
if (readNow == 0) {
Log.e(TAG, "Read Error: " + bytesToBeReadTemp);
return numBytesRead;
} else {
System.arraycopy(mReadBuffer, 0, dest, numBytesRead, readNow);
numBytesRead += readNow;
bytesToBeReadTemp -= readNow;
}
}
Log.v("Bytes Read", "" + numBytesRead);
return numBytesRead;
}
Код: Выделить всё
invokeMethodКод: Выделить всё
Future open() async {
return await _channel.invokeMethod("open");
}
Если возможно, рекомендуется ли это или нет мой подход, использующий комбинацию Future, async и await, лучше? Учитывая опыт работы с Java, такая реализация кажется сложной.
Подробнее здесь: https://stackoverflow.com/questions/793 ... ns-in-dart
Мобильная версия