susomena
susomena

Reputation: 133

Android: Force close when reading from Socket

I'm trying to make a client in Android. This clients runs a thread that creates the client socket and launches another thread that is always listening to the socket to receive Strings. Everything is OK when I send a String from the client to a Java server running in a PC, but when I send a String from the server to the Android client the app finishes. Why do I get this error?

Here is the code of the main Activity of the client:

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;

    import android.os.Bundle;
    import android.app.Activity;
    import android.view.Menu;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;

    public class MainActivity extends Activity {
        TextView chatHistorial;
        EditText msg;
        Socket client;
        DataInputStream in;
        DataOutputStream out;
        Boolean cerrar;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            Thread t = new Thread(new Runnable(){
                @Override
                public void run() {
                    try{
                        client = new Socket("192.168.1.33", 4444);
                        in = new DataInputStream(client.getInputStream());
                        out = new DataOutputStream(client.getOutputStream());
                        cerrar = false;

                        chatHistorial = (TextView) findViewById(R.id.chatHistorial);
                        msg = (EditText) findViewById(R.id.msg);

                        ThreadLectura tl = new ThreadLectura(in, cerrar, chatHistorial);
                        tl.start();
                    }
                    catch(Exception e){
                        // ...
                    }
                }
            });

            t.start();

            findViewById(R.id.enviar).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String cadena = msg.getText().toString();
                    try {
                        out.writeUTF(cadena);
                    } catch (IOException e) {
                        // ...
                    }
                    if(cadena.equals("exit"))
                        cerrar = true;
                }
            });
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            //getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }

    }

    class ThreadLectura extends Thread{
        DataInputStream in;
        String cadena;
        TextView chatHistorial;
        Boolean cerrar;

        public ThreadLectura(DataInputStream in, Boolean cerrar, TextView tv){
            this.in = in;
            this.cerrar = cerrar;
            chatHistorial = tv;
        }

        @Override
        public void run(){
            try{
                while(!cerrar){
                    cadena = in.readUTF();
                    chatHistorial.append("Has recibido: " + cadena);
                }
            }
            catch(IOException ioe){
                System.out.println("Error de entrada/salida: "+ioe.getMessage());
            }
        }
    }

Upvotes: 1

Views: 504

Answers (1)

dave.c
dave.c

Reputation: 10908

It's hard to say without seeing your logcat output, but I'm betting it's because you are attempting to modify the UI from within your background thread. This line within ThreadLectura:

chatHistorial.append("Has recibido: " + cadena);

is probably the issue, as chatHistorial is a TextView. You need to only modify the UI from within the main UI thread.

Upvotes: 2

Related Questions