Подождите, чтобы получить данные, не блокируя поток пользовательского интерфейса Bluetooth Android - PullRequest
0 голосов
/ 05 июля 2019

Я новичок в программировании на Android, и я пишу простое приложение пошаговой игры, которая использует Bluetooth.Мое приложение состоит из Main Activity, отвечающего за запуск соединения Bluetooth и обмен некоторыми сообщениями о конфигурации, и SecondActivity, реализующего пользовательский вид с игровой картой.Я могу правильно соединить устройства и обмениваться информацией между ними даже в пользовательском представлении, проблема в том, что в настраиваемом представлении я буду ждать получения информации, не блокируя поток пользовательского интерфейса, в данный момент я ожидаю получения данных таким образом

Пользовательское представление

state = bluetoothService.getState();
while(state != NOT_EMPTY){
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    state = bluetoothService.getState();
}
info = bluetoothService.getMessage();

это, очевидно, вызывает черные экраны и не отвечает, есть ли другой способ ожидания получения данных?

Управление соединением осуществляется через BluetoothServiceкласс с потоками, тот, который заботится о чтении данных, делает это

private class ConnectedThread extends Thread {
        private final BluetoothSocket mSocket;
        private final InputStream mInStream;
        private final OutputStream mOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = mSocket.getInputStream();
                tmpOut = mSocket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }

            mInStream = tmpIn;
            mOutStream = tmpOut;
        }

        public void run(){
            byte[] buffer = new byte[1024]; 

            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                // Read from the InputStream
                try {
                    bytes = mInStream.read(buffer);
                    if(bytes != 0) {
                        String incomingMessage = new String(buffer, 0, bytes);
                        message = incomingMessage;
                        mState = NOT_EMPTY;
                    }
                } catch (IOException e) {
                    break;
                }
            }
        }
}

//getMessage method just returns message if not null

1 Ответ

2 голосов
/ 05 июля 2019

Основная идея состоит не в том, чтобы извлекать действие, а вместо этого вызывать метод действия из фонового потока.

Поэтому при построении потока чтения читайте ссылку на действие и создайте обработчик.:

    private SecondActivity mActivity;
    private Handler mActivityHandler;

    public ConnectedThread(BluetoothSocket socket, SecondActivity activity) {
        mActivity = activity;
        mActivityHandler = new Handler(activity.getMainLooper());

        ...
    }

Когда сообщение получено, вызовите метод действия.Вызов должен быть выполнен в главном потоке, поэтому используйте обработчик:

final String message = incomingMessage;
Runnable runnable = new Runnable() {
    @Override 
    public void run() {
        mActivity.onMessageReceived(message);
    } 
};
mActivityHandler.post(myRunnable);

В упражнении сделайте что-нибудь с сообщением:

public void onMessageReceived(String message) {
    // handle the message...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...