1

I am trying to make a simple chat server/client application. My server is made in python, using twisted. Everything works good with it, tested it with telnet.

Basically the server sends to all it's clients every message it's getting. I need a way to read forever from the socket, so that I can get all messages. I don't think it's the best approach, but I tried to make it using a thread, that reads forever (for now). After the client is connected to the server, it will start a thread, that will check forever for updates.

Here is my CheckUpdates class that implements Runnable:

class CheckUpdates implements  Runnable{
    @Override
    public void run() {
       Log.d("ME", "CHECKING FOR UPDATES");
        while(true)
        {
            // reader.lines().forEach(System.out.println);
            String line;
            Log.d("ME","IN WHILE");
            try {
                while ((line = reader.readLine()) != null) {
                    Log.d("ME", "READING LINE");
                    Looper.prepare();
                    Toast.makeText(MainActivity.this, line, Toast.LENGTH_SHORT).show();
                    Looper.loop();
                }
            } catch (IOException e) {
                Log.d("ME", "EXCEPTION IN WHILE: " + e.getMessage().toString());
            }
            Log.d("ME", "END OF WHILE CHECK UPDATES");
        }
    }
}

I am starting the thread right after I'm connected to the server. Basically, I am getting the first message (first toast), and right after that, nothing more comes in, not even the END OF WHILE CHECK UPDATES logcat message.

Could it get stuck forever in the while that checks for a new line from socket ? Also, if there is a more elegant way of doing this, would really appreciate if somebody could point me in the right direction.

user1812076
  • 269
  • 5
  • 21

2 Answers2

2

Could it get stuck forever in the while that checks for a new line from socket ?

No, but it could get stuck forever in the outer while (true) loop, which is completely pointless. Remove it. At the moment you're looping forever at end of stream.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I want to loop forever, because I want to get all the messages. I guess that if I take the while out, I'll get only the first one or ... ? – user1812076 Dec 18 '14 at 09:17
  • @user1812076: No, you've already got a `while` loop inside as well, so that you loop over all the lines. You really don't need that `while (true)`. (I missed that...) – Jon Skeet Dec 18 '14 at 09:22
  • You're totally right. If I don't show any Toast, and just check with logcat, everything works fine. I get every message, but how could I update the UI thread (or show a toast) with each message ? Basically that's the ultimate goal. – user1812076 Dec 18 '14 at 09:23
  • 1
    @user1812076 No, you *don't* 'want to loop forever'. You want to loop until end of stream, and that's what your inner `while` loop does. Your *outer* while loop is just a bug. There can't be any messages after end of stream. The meaning of your second comment eludes me entirely. – user207421 Dec 18 '14 at 09:24
  • you're right thanks. But still, I need to let the user know that a new message arrived, how do I show a toast without looper or how do I update element on the UI ? – user1812076 Dec 18 '14 at 09:25
  • 1
    I'm no Android expert, but it seems to be that you're already doing that. In any case it's a new question. – user207421 Dec 18 '14 at 09:26
1

Could it get stuck forever in the while that checks for a new line from socket?

Yes, if there's no more data. But I suspect that's not the problem. I suspect the problem is this:

Looper.loop();

As far as I can see, you don't need to use Looper at all here. Assuming you're really on a dedicated thread, what messages do you expect to process? With nothing calling Looper.quit(), the Looper.loop() call will block forever, I suspect.

Just get rid of the two Looper calls and I suspect you'll be able to see all the messages.

EDIT: However, you'll need to show the toast on the UI thread - see this SO question for details of that, using Activity.runOnUiThread. I'm not sure that showing a toast on every message is an ideal UI, mind you...

You'll also want to get rid of the while (true) - you're already looping on the inner loop, so that's fine.

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • If I take looper out, it will throw an exception, because I am not showing the toast from the UI thread. But yes, looks like Loooper.loop is the problem. How could I update the main thread from another thread without Looper ? – user1812076 Dec 18 '14 at 09:17
  • @user1812076: Ah, missed that about the toast. Right, so you should do *just that* on the UI thread, with `Activity.runOnUiThread`. See http://stackoverflow.com/questions/3134683/android-toast-in-a-thread – Jon Skeet Dec 18 '14 at 09:23