Невозможно создать ObjectInputStream с InputStream для сокета Bluetooth на платформе Android

Я пишу многопользовательскую игру для телефонов Android. Связь осуществляется через Bluetooth. Мне удалось отправить байты с одного телефона на другой, используя поток ввода/вывода. Поскольку мне нужно иметь возможность передавать объекты, мне нужны потоки объектов. Однако, когда я пытаюсь создать Objectstream со своими потоками, моя программа зависает на инструкции.

public class ConnectedThread extends Thread {
private static final String TAG = "Connected Thread";
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private Handler mHandler;
private ObjectInputStream ois;
private ObjectOutputStream oos;

public ConnectedThread(BluetoothSocket socket,Handler h) {
    mmSocket = socket;
    mHandler = h;

    InputStream tmpIn = null;
    OutputStream tmpOut = null;

    // Get the input and output streams, using temp objects because
    // member streams are final
    try {
        tmpIn = socket.getInputStream();
        tmpOut = socket.getOutputStream();
    } catch (IOException e) { }

    mmInStream = tmpIn;
    mmOutStream = tmpOut;
    Log.d(TAG,"attempting to create OIS");

    try {
    ois = new ObjectInputStream(mmInStream);

// Инструкция new ObjectInputStream(mmInStream) НИКОГДА НЕ ЗАВЕРШАЕТ ВЫПОЛНЕНИЕ. Кажется, это не выдает ошибку, потому что я бы ее поймал. Просто зависает на этой инструкции. Ни один код ниже этой строки никогда не выполняется.

    } catch (Exception e) {

        Log.e(TAG,"Error");
        Log.d(TAG,e.getMessage());
        e.printStackTrace();
    } 

    Log.d(TAG,"attempting to create OOS");
    try {
        oos = new ObjectOutputStream(mmOutStream);
    } catch (IOException e) {
        Log.e(TAG,"IO exception for Output Stream, I have no idea what caused this");
        Log.d(TAG,e.getMessage());
    }

}

public void run() {.....}

Что я делаю не так?


person Alexander    schedule 09.04.2011    source источник


Ответы (3)


Просто создайте ObjectOutputStream, и flush() с обоих концов до построения ObjectInputStream.. Вам не нужно записывать какие-либо собственные данные.

person user207421    schedule 16.04.2011
comment
Можете ли вы привести пример в коде? У меня такая же проблема, и я не совсем понимаю ваше решение... - person jpmastermind; 31.03.2013
comment
не могли бы вы немного уточнить. Я не получил вашего решения. - person Ana; 16.01.2014
comment
@Kake Смотрите редактирование. Я не вижу, как это может быть яснее, чем это. - person user207421; 16.01.2014

Как предложил EJP...

        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        oos.flush();
        ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
person eric.mcgregor    schedule 24.04.2015

Ладно, кажется, я знаю, что я сделал не так. Потоки объектов более сложны, кажется, конструктору ObjectInputStream нужны данные для работы, прежде чем он создаст поток. Я решил эту проблему с помощью

  1. Создание ООС.
  2. Запустите конструктор для OIS в отдельном потоке.
  3. Запишите некоторые данные в OOS и сбросьте их.
  4. Подождите, пока OIS инициализируется, прежде чем читать из него.

Это то, что я использую сейчас (обратите внимание, что я также добавил буфер):

public ConnectedThread(BluetoothSocket socket,Handler h) {
    mmSocket = socket;
    mHandler = h;

    InputStream tmpIn = null;
    OutputStream tmpOut = null;

    // Get the input and output streams, using temp objects because
    // member streams are final
    try {
        tmpIn = socket.getInputStream();
        tmpOut = socket.getOutputStream();
    } catch (Exception e) { 
        Log.d(TAG,"Error in getting Input Streams");
        Log.w(TAG,e);

    }

    mmInStream = tmpIn;
    mmOutStream = tmpOut;


    Log.d(TAG,"The socket is: " + mmSocket);
    Log.d(TAG,"The streams are: " + mmInStream + mmOutStream);
    Log.d(TAG,"attempting to create BufStreams");

    final BufferedOutputStream bufo = new BufferedOutputStream(mmOutStream);
    final BufferedInputStream bufi = new BufferedInputStream(mmInStream);

    Log.d(TAG,"attempting to create OOS");

    try {
        oos = new ObjectOutputStream(bufo);



    } catch (StreamCorruptedException e) {
        Log.d(TAG,"Caught Corrupted Stream Exception");
        Log.w(TAG,e);

    } catch (IOException e) {
        Log.d(TAG,"Caught IOException");
        Log.w(TAG,e);
    }

    Log.d(TAG,"done OOS");

    if(oos==null)
      {
           Log.d(TAG,"oos is null!!!!");
      }


    Thread s = new Thread(){
        public void run(){
            Log.d(TAG,"attempting to create OIS");
            try {
                ois = new ObjectInputStream(bufi);
            } catch (StreamCorruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Log.d(TAG,"completed OIS");
            if(ois == null)
            {
                Log.d(TAG,"OIS is null");
            }
        }




    };
    s.start();
    try {
        Log.d(TAG,"writing and flushing 1");
        oos.write(1);
        oos.flush();
    } catch (IOException e1) {
        Log.d(TAG,"CaugtIOexception");
        Log.w(TAG,e1);
    }
    Log.d(TAG,"sleeping to make sure stream is set up");
    while (ois == null) {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }


    }
    Log.d(TAG, "done Sleeping");

    // Read out the 1 to make sure everything is okay 

    int i = 0;

    try {
        i = ois.read();
    } catch (IOException e) {
        Log.d(TAG, "error reading");
        e.printStackTrace();
    }


    Log.d(TAG,"I received an i of: " + i);
    Log.d(TAG,"OO Streams set up");




}

public void run() {...
person Alexander    schedule 16.04.2011
comment
Это все чепуха. StreamCorruptedException не создается при создании ObjectOutputStream. Все, что вам нужно сделать, это сначала создать ObjectOutputStream на обоих концах. - person user207421; 09.08.2011
comment
Сначала я создаю ObjectOutputStream, очищаю его, а затем создаю потоки ввода. А также сброс выходного потока после записи. Я все еще получаю проблему зависания. - person Siddharth; 22.04.2013