0

I'm trying to write this program which updates itself on the current status of a variable. How I intended it to work is by having a timed task to constantly send the string "update" to the server. The server will recognize the string and will send the necessary values for the variable on the android device. However, I am facing some problems. The string "update" is sending without error but when the corresponding value from the server is sent back, the program does not seem to be able to read the reply. Here is the code:

            //Open socket and initialize data streams
    try {
        socket = new Socket(serverIpAddress, applicationport);
        //in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //in = new DataInputStream(socket.getInputStream());
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                socket.getOutputStream())), true);
    } catch (UnknownHostException ex) {
        // TODO Auto-generated catch block
        ex.printStackTrace();
        ShowDialog("Login Error" + ex.getMessage());
    } catch (IOException ex) {
        // TODO Auto-generated catch block
        ex.printStackTrace();
        ShowDialog("Login Error" + ex.getMessage());
    }

    //Create new daemon timer
    updateData = new Timer(true);
    updateData.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            out.println("update");
            UpdateMethod();
            }//run
        }, 1000, 10000);//schedule the delays start/interval here



};

private void UpdateMethod() {
    //This method is called directly by the timer
    //and runs in the same thread as the timer.
    //It calls the method that will work with the UI
    //through the runOnUiThread method.
    this.runOnUiThread(Timer_Tick);
};//timermethod

private Runnable Timer_Tick = new Runnable() {
    public void run() {
        try {
            //in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //String getx1 = null;
            //getx1 = in.readLine();
            //if (getx1 != null) {
                //float updatex1 = Float.parseFloat(getx1);
                //get_x1 = getx1;
                //}
            in = new DataInputStream(socket.getInputStream());
            /*try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/
            x1display = (TextView) findViewById(R.id.x1display);
            x1display.setText(in.readUTF());

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally {
            if (in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
};

As you can see, I have tried experimenting with both DataInputStream and BufferedReader as well but to no avail.

Edit: It seems that trying to read from the input stream is causing my UI to freeze up. I have no idea what is wrong as my code seems to be without errors..

Any help or advice would be greatly appreciated!

Thank you!

Pooty
  • 11
  • 3

2 Answers2

0

As you have already said, reading blocks the thread. You shouldn't ever read something inside the UI thread! Furthermore, as I remember correctly, closing input before closing output does some nasty things. I would suggest closing the socket instead and putting the BufferedReader back in. This is how it should look like:

//Open socket and initialize data streams
try {
    socket = new Socket(serverIpAddress, applicationport);
    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
            socket.getOutputStream())), true);
} catch (UnknownHostException ex) {
    ex.printStackTrace();
    ShowDialog("Login Error" + ex.getMessage());
} catch (IOException ex) {
    ex.printStackTrace();
    ShowDialog("Login Error" + ex.getMessage());
}

//Create new daemon timer
updateData = new Timer(true);
updateData.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        out.println("update");
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    x1display = (TextView) findViewById(R.id.x1display);
                    x1display.setText(in.readUTF());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }}, 1000, 10000);//schedule the delays start/interval here

By the way, don't use printStackTrace(): Why is exception.printStackTrace() considered bad practice?

Community
  • 1
  • 1
0101100101
  • 5,786
  • 6
  • 31
  • 55
0

The code looks fine to me. But its not working so looks like you need to chop it up.

  • Test if the socket stuff is working without the Timer. Make a socket connection and read its response without the Timer and UI code

  • If that works, introduce the Timer but not the UI code

  • If that works, do the whole thing (which is failing now)

Somewhere in this test process you should be able to find the culprit

openmobster
  • 1,027
  • 5
  • 17
  • Hi openmobster, I have tried to troubleshoot it in this manner before posting on stackoverflow. The socket is working perfectly, the timer is working as well as my server is receiving the "update" string on a periodically basis but for some strange reason I am unable to touch any of my other buttons or receive the server inputs on the android client. Touching any button causes the app to crash. – Pooty Mar 20 '12 at 14:16
  • Something is freezing your UI and crashing making it look like its your buttons that are crashing. Looking at the code, may be this line under TimerTick could be frozen waiting on input from the socket: x1display.setText(in.readUTF()); This executes on the UI thread. Maybe try reading the inputstream inside timer task and providing the value to UpdateMethod as a parameter – openmobster Mar 20 '12 at 15:41
  • Hi openmobster, it seems you are right. I've narrowed down the culprit to the reading of the input stream to what's causing my app to crash. However I have no idea how to fix it as my code seems logical and right. This is definitely driving me nuts. :( – Pooty Mar 20 '12 at 20:58
  • make sure the server is actually writing something back. I know you mentioned that the update makes it. But is the socket being written to by the server. Just a hunch – openmobster Mar 20 '12 at 21:14