1

Right now I'm able to send JSON strings to my Android app over the network fine. The only thing is that the messages are no larger than a few hundred characters long at the moment. This will soon expand to thousands of characters per JSON string. How can I ensure that I've received the entire JSON string before sending it to the parser (which would otherwise crash)?

For example, a basic way of how I'm receiving data in a Thread:

while (true) 
{
    try 
    {
        // Read from the DataInputStream
        bytes = mmDataIn.read(buffer); //buffer is a 4096 size byte[]
        Log.d("JSON", "dataread: " + String.valueOf(bytes)); //only prints stuff > 0
        parseJSON(buffer); //will not work unless full JSON
    } 
    catch (IOException e) 
    {
        Log.e("JSON", "disconnected", e);
        break;
    }
}

I was planning on using a StringBuilder to piece together the JSON string, but I don't know how to tell when it is done.

I was reading this: How to identify end of InputStream in java

But what would be the best way to do it for a JSON string? I'm assuming this is very common and there's a standard way of handling it. Thanks.

Community
  • 1
  • 1
telkins
  • 10,440
  • 8
  • 52
  • 79

1 Answers1

1

If your receive more data than you buffer can hold, you'll have to either choose a larger buffer, or repeatedly read the input stream into the buffer, and concatenate the resulting json, before passing it into your parseJSON method.

For any InputStream, if read returns -1 it means that the end of the input stream was reached, so this also applies to your DataInputStream.

Cheers, Tom

Tom
  • 1,414
  • 12
  • 21
  • So just make my buffer a ridiculous size like 65536? Would rather do it with the StringBuilder method, but read is never returning -1. – telkins Aug 06 '12 at 20:54
  • The read method returns (javadoc) "the total number of bytes read into the buffer, or -1 if there is no more data because the end of the stream has been reached." So if it keeps returning > -1, it means that it hasn't finished yet. Or do you mean that the call to read blocks, and does not return anything at all? – Tom Aug 07 '12 at 07:02
  • Yes, the call to read blocks. I run it in a separate Thread to avoid that, but it doesn't help with having it return -1. – telkins Aug 07 '12 at 07:16
  • I'm not sure I can follow you here. I don't see how running this in a separate thread avoids the blocking call: it still blocks, right? And if it blocks you won't get your json. I would say the problem is the fact that it blocks. This means that the remote server is not sending any data anymore (because the entire json has been sent?), but it hasn't closed the connection, so your client is not aware of the fact that all data has been received, and simply keeps waiting for more data to arrive. But I also notice you are catching IOException. Is it thrown in your situation? – Tom Aug 07 '12 at 07:32
  • Sorry, it doesn't avoid the actual blocking but it allows my app to run fine in the meantime since only the network Thread is blocked. This app is continually downloading JSON data so the connection will only close when the user disconnects from the server. I think the only solution I can really do is to try and send the length before sending any packets. Not ideal, but I don't see much for non-blocking sockets on Android. – telkins Aug 07 '12 at 14:33