Ошибка в получении данных с использованием фреймворка MPC в игре libgdx

Мы пытаемся установить многоранговое соединение между двумя устройствами, используя инфраструктуру MPC в игре libgdx.

Что в целом мы сделали успешно:

  1. Устройства подключаются, сессия устанавливается корректно.
  2. После того, как сессия установлена, NearBrowser и NearAdvertiser перестают выполнять свои функции.
  3. Затем делаем переход к игровой сцене. В новой сцене одно устройство может отправить сообщение другому.
  4. Вызывается метод DidReceiveData из Session Delegate, и мы получаем правильные сообщения для обоих устройств.
  5. После этого мы отправляем в libgdx сообщение для обновления контента (в основном потоке gdx).

НО через некоторое время когда какое-то устройство получило данные оно тут же вылетает. Иногда бывает на 10-м приеме, иногда после 200-го. Сбой появляется только на устройстве, которое получило сообщение. Неважно, как долго они связаны. Сбой появляется после того, как все методы сделали свою работу с данными. Поэтому мы не знаем, где именно происходит ошибка.

// MCSession delegate method

public void didReceiveData(MCSession session, NSData data, MCPeerID peerID) {

 //there we make userInfoData

 // 
 DispatchQueue.getMainQueue().async(new Runnable() {
  @Override
  public void run() {
        NSNotificationCenter.getDefaultCenter().postNotification(new NSString("didReceiveData"), null,  userInfoData);
  }
  });

}

// Register observer in NSNotificationCenter
// NSNotificationCenter.getDefaultCenter().addObserver(this, Selector.register("updateDataWithNotification:"), new NSString("didReceiveData"), null);

// This method is called when device has received new data

@Method
private void updateDataWithNotification(NSNotification notification){

 userInfoDict = notification.getUserInfo();
 data = (NSData) userInfoDict.get(new NSString("data"));
 strBytes =  new String(data.getBytes());

 // i'm not sure this Gdx.app.postRunnable is really needed         
 Gdx.app.postRunnable(new Runnable() {
    @Override
    public void run() { 
  SBGlobalMessanger.getInstance().readBluetoothMessage(BluetoothData.RC_MESSAGE, strBytes);
    }
 });
}

Вопросы: Где ошибка? И как мы можем это исправить?


person E A    schedule 19.03.2015    source источник
comment
Я не вижу ошибки. Но ваш код слишком сложен. Зачем нужен сигнал? Вы поступаете правильно, отправляя в основную очередь метод делегата (который выполняется в другой очереди), но почему бы просто не вызвать метод обработчика напрямую, без сигнала?   -  person bootchk    schedule 07.04.2015
comment
В любом случае, даже если я обрабатываю данные напрямую, я получаю сбой. Причина использования уведомлений — разделение классов. Один единственный обработчик реализует MCSessionDelegate, MCNearbyServiceBrowserDelegate, MCNearbyServiceAdvertiserDelegate. Второй класс реализует другие интерфейсы, которые находятся на более высоком уровне абстракции. Вот почему я создал 2 класса, которые используют наблюдателя вместо 1 большого.   -  person E A    schedule 08.04.2015
comment
Вы можете отсоединиться без использования уведомлений. Я использовал Messenger другого класса, так что мой didReceiveData делает: dispatch_async(dispatch_get_main_queue()) { messenger.receive(data!)}. Я могу ошибаться, просто предполагая, что ошибка связана с каким-то сложным взаимодействием между уведомлениями и очередями.   -  person bootchk    schedule 13.04.2015


Ответы (1)


Проблема была в плагине robovm. В режиме отладки он сделал сборку, которая раздавила. После создания релизной сборки ошибка исчезла. После работы с robovm + libgdx я понял, что если у вас есть странная ошибка, просто сделайте релизную сборку. Кажется, этот вид ошибок был устранен с последним выпуском robovm 1.3 (я еще не пробовал).

person E A    schedule 08.06.2015