Головоломка: интервал отправки данных Bluetooth сокращается вдвое после каждого повторного подключения

Я изменил стандартный пример Bluetoothchat, чтобы отправлять 4 байта данных за раз на устройство Bluetooth каждые полсекунды. Он отлично работает, если я запускаю приложение заново. Однако возникает проблема, если я повторно подключаюсь следующим образом:

Пока Bluetooth подключен, я снова нажимаю кнопку подключения в меню и выбираю то же устройство. Это отключает bluetooth (не уверен, что это правильная процедура отключения). Затем я снова подключаюсь, выбрав устройство, и оно будет снова подключено. После переподключения появляется очень странная проблема: вместо того, чтобы отправлять данные каждые полсекунды, он будет отправлять данные каждые четверть секунды. Если я пройду процесс еще раз и переподключусь, временной интервал станет еще короче. Доходит до того, что устройство Bluetooth на принимающей стороне не справляется с данными. На данный момент единственный выход — убить приложение и перезапустить его снова. Потом все становится нормально, пока в следующий раз не попытаюсь снова подключиться.

Я пробовал разные вещи, но ничто не могло исправить это. Например, я убедился, что поток, отправляющий данные, уничтожается при отключении, поэтому несколько потоков не отправляют данные. Мне было интересно, изменилась ли скорость передачи данных при повторном подключении, но тогда почему скорость передачи данных влияет на Thread.sleep(500); оператор (который отвечает за управление отправкой данных за полсекунды). Любая помощь будет принята с благодарностью.

Вот код, SendClass создается под MainActivity:

class SendClass implements Runnable {
public void run() {
    bytearr[0]=0;bytearr[1]=0;bytearr[2]=0;bytearr[3]=0;
        while (!Thread.currentThread().isInterrupted()) {
        if (mChatService==null ||  mChatService.getState()          
                          !=BluetoothChatService.STATE_CONNECTED) {
        continue;
} else {
          try {
         Thread.sleep(500);
          } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
          }
        mChatService.write(bytearr);

                }
            }//end of run
        }//end of runnable

Затем в STATE_CONNECTED:

                case BluetoothChatService.STATE_CONNECTED:

                setStatus(getString(R.string.title_connected_to,mConnectedDeviceName));

                    /*
                    if(sendingThread!=null){
                        //sendingThread.stop();
                        sendingThread.interrupt();
                        if(D) Log.i(TAG, "after sendingThread");
                        sendingThread = null;
                    }*/
                    sendingThread = new Thread(new SendClass());
                    sendingThread.start();

                    break;

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


person Terrapin    schedule 23.03.2013    source источник
comment
Похоже, вы создаете несколько потоков, чтобы сделать одно и то же. Разместите свой код.   -  person alex    schedule 24.03.2013
comment
класс SendClass реализует Runnable { public void run() { bytearr[0]=0;bytearr[1]=0;bytearr[2]=0;bytearr[3]=0; в то время как (!Thread.currentThread().isInterrupted()) {   -  person Terrapin    schedule 26.03.2013


Ответы (1)


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

Измените свой SendClass на:

class SendClass implements Runnable {
private boolean stopped = false;
public void setStopped(boolean s){
  this.stopped = s;
}
public void run() {
bytearr[0]=0;bytearr[1]=0;bytearr[2]=0;bytearr[3]=0;
    while (!Thread.currentThread().isInterrupted() && !stopped) {
    if (mChatService==null ||  mChatService.getState() !=BluetoothChatService.STATE_CONNECTED) {
     continue;
    } else {
         try {
           Thread.sleep(500);
         } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
         }
         mChatService.write(bytearr);

         }
        }//end of run
    }//end of runnable

Затем, когда вы начинаете свой поток, сохраняйте ссылку на Runnable, чтобы вы могли вызывать setStopped(true);, как это

SendClass sc = new SendClass();
sendingThread = new Thread(sc);
sendingThread.start();

Когда вы отключите bluetooth, не забудьте вызвать sc.setStopped(true);, чтобы ваш поток завершился, не переходя в режим while.

person Gabriel Netto    schedule 28.03.2013