Cannot create ObjectInputStream with InputStream for a Bluetooth Socket on the Android Platform

谁都会走 提交于 2020-01-01 02:51:10

问题


I am writing a multiplayer game for Android phones. Communication is via Bluetooth. I have managed to send bytes from one phone to the other using the input / output stream. Since I need to be able to transfer objects I want objectstreams. However, when I try to create an Objectstream with my streams, my program hangs on the instruction.

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);

// The instruction new ObjectInputStream(mmInStream) NEVER FINISHES EXECUTING. It doesn't seem to throw an error, because I'd catch it. It just hangs at this instruction. None of the code below this line is ever executed.

    } 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() {.....}

What am I doing wrong?


回答1:


Just construct the ObjectOutputStream, and flush() it, at both ends before constructing the ObjectInputStream. You don't have to write any data of your own.




回答2:


As EJP suggested ...

        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
        oos.flush();
        ObjectInputStream is = new ObjectInputStream(socket.getInputStream());



回答3:


Alright, I think I know what I did wrong. Object Streams are more complicated, it seems the ObjectInputStream constructor needs data to work on before it creates the the stream. I solved this problem by

  1. Creating the OOS.
  2. Start the constructor for the OIS in a seperate thread.
  3. Write some data into the OOS and flush it.
  4. Wait for the OIS to become initialized before reading from it.

This is what I'm using now (note that I also added a buffer):

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() {...


来源:https://stackoverflow.com/questions/5605153/cannot-create-objectinputstream-with-inputstream-for-a-bluetooth-socket-on-the-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!