Hi,

Using main UI thread for reading tcp socket data is a bad idea. You
should create a separate Thread and run your Runnable there in an
infinite loop (until connection is closed).
Doing this you eliminate 100ms delays and remove hiccups in your GUI
main thread.
My second advice is to use read(byte[] buffer, int offset, int length)
instead of reading bytes one by one. Allocate a byte buffer with N
bytes length and read from socket to this buffer.
read(...) will return the number of actually read bytes. Put these
bytes to your parser then.

So, here is a schema:
- create java.lang.Thread
- pass Runnable to it
- call Thread.start to start your runnable in a separate thread.
- in your runnable
 - connect to the server (gateway)
 - allocate byte buffer
 - do blocked read to the buffer from the socket you acquired on
connect. Calling read will wait until data is arrived and then return.
 - process your data with the parser
- if socket was close or all data read, exit from your run method and
thread will die automatically.

Hope this helps.

P.S: I think you will also need to send data back to the server, then
do it in a separate thread too. Send messages from main UI thread to
that helper thread using Handler class and there you can put the data
to the output stream.


On Oct 4, 12:17 pm, simon <wbr...@googlemail.com> wrote:
> Hi,
>
> in my application I need to send and receive data bytewise over TCP.
> At the beginning of development I tried to implement that
> functionality as resource-efficient as possible.
> So I finally decided to use Messages (android.os.Message) to
> cyclically initiate reading bytes from socket.
> After establishing the connection I assign Input- and OutputStream and
> order Android to execute the runnable "readFromSocket" after 100ms:
>
>   OutputStream out = null;
>   InputStream in = null;
>   Handler readInputHandler;
>
>   Socket gateway = new Socket();
>   gateway.connect(new InetSocketAddress(address, port), 20000);
>
>   if (gateway.isConnected()) {
>     in = gateway.getInputStream();
>     out = gateway.getOutputStream();
>
>     readInputHandler.postDelayed(readFromSocket, 100);
>   }
>
> The runnable reads one byte after another and passes it to a parser
> that tries to assemble the single bytes to an instruction (if the
> parser is successful I send the instruction encapsulated in a Message
> to a Controller-Object). At the end it orders its own execution after
> another 100ms:
>
>   private Runnable readFromSocket = new Runnable() {
>     byte[] input = new byte[1];
>
>     @Override
>     public void run() {
>       try {
>         while (in.available() > 0) {
>           in.read(input);
>           parser.parse(input[0]);
>         }
>       } catch (IOException e) {
>         // InputStream unavailable
>         e.printStackTrace();
>       }
>
>       // Initiate reading after 100 ms
>       readInputHandler.postDelayed(this, 100);
>     }
>   };
>
> After testing my app on two different devices (Sony Ericsson Xperia
> neo and Acer Iconia Tab) I currently hesitate whether that
> implementation is the best solution...
> When sending many bytes to the Xperia neo it often takes seconds until
> my app has received all bytes.
> In comparison, on the Iconia Tab there isn't such a big delay but the
> performance also isn't very well.
>
> What is the best solution to implement that functionality for an
> Android-App?
>
> Thanks in advance.

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to