简体   繁体   中英

Thread causes program to crash

I am new to Android Development, but not new to Java.

One golden rule is to never block the GUI thread, nor the main thread.

The problem I am facing is that my app can send messages to a server, and the server displays the messages. When my server(PC) sends messages back to my android app, the app receives the message, and this is evident due to the log method .

The console, displays the message sent from the server, but the GUI app does not, this is because it freezes.

What I have done is set a thread, in side another thread. `Main Thread > Thread(Connects to server) > Thread (Listens for incoming messages) > Thread (The Android Gui Thread).

The problem here is; the program freezes and the activity stops responding. Butt the console window does display the messages sent from the server.

My question is, why is the app freezing, when I'm not blocking any threads?

private void ConnectButtonPress() {
    btnConnect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            btnConnect.setVisibility(View.GONE);
            btnDisconnect.setVisibility(View.VISIBLE);
            btnSend.setEnabled(true);
            enterET.setEnabled(true);
            new Thread(new Runnable() {
                public void run(){
                    try {
                        socket = new Socket(IPAddressET.getText().toString(), Integer.parseInt(portET.getText().toString()));  //connect to server
                        input = new Scanner(socket.getInputStream());

                        pw = new PrintWriter(socket.getOutputStream(), true);
                        pw.println(usersName);  //write the message to output stream
                        pw.flush();

                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                while (true){//this is where the problem is 
                                    try {
                                        input = new Scanner(socket.getInputStream());
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }

                                    String message = input.nextLine();
                                    Log.i("LOL",message);
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            String message = input.nextLine();

                                            displayMessages.append(message +"\n");
                                        }
                                    });
                                }
                            }
                        }).start();



                        //pw.close();
                        //pw.close();   //closing the connection
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();




        }
    });
}

Well, this block:

runOnUiThread(new Runnable() {
@Override
public void run() {
    String message = input.nextLine();

    displayMessages.append(message +"\n");
}
});

is run indefinitely inside the while loop, and hence blocks the main thread. Why do you need to build your displayMessages in the main thread? I guess you can just put displayMessages.append(message +"\\n"); inside your while loop.

If I'm not wrong, input.nextLine(); blocks the thread until a message is received from the server.

So, if I'm correct, when you receive a new message from the server, you run on the main thread to change the text view you have... but in the runOnUiThread you again call the input.nextLine(); , when you already have read its value( String message = input.nextLine(); ), just before the runOnUiThread(new Runnable() {... call.

This basically causes, your main thread to wait for a new message from the server. You just have to use the value you already have, or, I suppose you can also play with the hasNextLine() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM