Как справиться с записью в OutputStream BluetoothSocket в Android? - PullRequest
0 голосов
/ 02 октября 2019

Документы для разработчиков Android говорят, что обе функции read(byte[]) и write(byte[]) блокируют вызовы, поэтому их не следует вызывать напрямую из основного потока.

Я понимаю, что read() возвращается только тогда, когда есть что-то, что нужно прочитать из сокета, но я должен порождать новый поток каждый раз, когда мне нужно записать байт в выходной поток сокета, используя write() поскольку в документах сказано, что эта функция тоже может блокироваться, если принимающая сторона недостаточно быстро читает из сокета.

Далее, в примере с документами они просто вызвали write() напрямую и дажепрокомментировал это, сказав, что функция должна быть вызвана непосредственно из деятельности.

Так каков правильный способ справиться с ситуацией, когда write() блокирует, чтобы предотвратить зависание моего приложения и, в конечном итоге, выброс ANR? Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 октября 2019

У вас может быть «запись потока», который начинается при создании вашего сокета. Затем используйте некоторую форму передачи сообщений, чтобы отправить сообщение из основного потока, содержащее данные для отправки. «Записывать поток» блокируется при ожидании новых сообщений. Когда он получает сообщение, он записывает данные в сокет. Просто не забудьте выйти из потока, когда сокет закрывается.

С Android вы можете использовать Handler и Looper для создания рабочего потока, который может обрабатывать сообщения. См., Например, https://blog.mindorks.com/android-core-looper-handler-and-handlerthread-bd54d69fe91a.

Но если получатель фактически читает медленнее, чем вы отправляете, убедитесь, что вы не просто публикуете все больше и больше сообщений быстрее, чем они обрабатываются, или в конечном итоге вам не хватит памяти.

0 голосов
/ 02 октября 2019

В BLE вызовы BluetoothGatt readCharacteristic() и writeCharacteristic() не блокируются. Они возвращают true, если операция была успешно начата.

Когда операция будет завершена, вы получите результаты реализации BluetoothGattCallback onCharacteristicRead() и onCharacteristicWrite()

Если вам нужночтобы отобразить некоторые результаты в вашем пользовательском интерфейсе, выполните следующие операции в потоке пользовательского интерфейса:

getActivity().runOnUiThread(new Runnable() {

            @Override
            public void run() {
                // UI operations ...
            }
        });

Для получения дополнительной информации о writeCharacteristic() https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic)

...