线程导致程序崩溃

时间:2015-04-22 00:22:32

标签: java android multithreading

我是Android开发人员的新手,但不是Java新手。

一条黄金法则是永远不会阻止GUI线程,也不会阻塞主线程。

我面临的问题是我的应用可以向服务器发送消息,服务器会显示消息。当我的服务器(PC)将消息发送回我的A​​ndroid应用程序时,应用程序会收到消息,这很明显是由于log method

控制台显示从服务器发送的消息,但GUI应用程序没有,这是因为它冻结了。

我所做的是在另一个线程中设置一个线程。 `主线程>线程(连接到服务器)>线程(侦听传入的消息)>线程(Android Gui线程)。

这里的问题是;程序冻结,活动停止响应。对话框窗口确实显示从服务器发送的消息。

我的问题是,当我没有阻止任何线程时,为什么应用程序会冻结?

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();




        }
    });
}

2 个答案:

答案 0 :(得分:2)

好吧,这个街区:

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

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

while循环内无限期运行,因此会阻塞主线程。为什么需要在主线程中构建displayMessages?我想你可以将displayMessages.append(message +"\n");放在while循环中。

答案 1 :(得分:1)

如果我没错,input.nextLine();会阻止线程直到从服务器收到消息。

因此,如果我是正确的,当您从服务器收到新消息时,您将在主线程上运行以更改您拥有的文本视图...但是在runOnUiThread中您再次调用input.nextLine(); ,当你已经在String message = input.nextLine();电话会议之前阅读了它的值(runOnUiThread(new Runnable() {...)。

这基本上会导致您的主线程等待来自服务器的新消息。您只需使用您已有的值,或者,我想您也可以使用hasNextLine()