Мы пытаемся установить многопользовательское соединение между двумя устройствами, используя платформу 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);
    }
 });
}

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

0
E A 19 Мар 2015 в 13:10
Я не вижу ошибки. Но ваш код слишком сложен. Зачем нужен сигнал? Вы поступаете правильно, отправляя в основную очередь из метода делегата (который выполняется в другой очереди), но почему бы просто не вызвать метод обработчика напрямую, без сигнала?
 – 
bootchk
7 Апр 2015 в 22:20
В любом случае, даже если я обрабатываю данные напрямую, я получаю сбой. Причина использования уведомлений - разделение классов. Один синглтон-обработчик реализует MCSessionDelegate, MCNearbyServiceBrowserDelegate, MCNearbyServiceAdvertiserDelegate. Второй класс реализует другие интерфейсы, которые находятся на более высоком уровне абстракции. Вот почему я создал 2 класса, которые используют наблюдателя вместо одного большого.
 – 
E A
8 Апр 2015 в 11:26
Вы можете разъединить без уведомления. Я использовал другой класс Messenger, поэтому мой didReceiveData делает: dispatch_async (dispatch_get_main_queue ()) {messenger.receive (data!)}. Я мог ошибаться, просто предполагая, что ошибка - это какое-то сложное взаимодействие между уведомлениями и очередями.
 – 
bootchk
13 Апр 2015 в 18:16

1 ответ

Лучший ответ

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

0
E A 8 Июн 2015 в 11:36