android进行Tcp通信时readLine阻塞问题

串口工具作为服务端往App发送数据内容时,App这边没有接收到,在我关闭串口工具时,App接收到了,感觉是线程阻塞的问题。后来用Wireshark监控了一下,发现串口工具(服务端)是在一始就发送的,不知道为什么,在我关闭串口工具之后,App端才收到数据内容。然后,我就发现我被readLine()方法给坑了,有没有什么方法解决我一下代码中的readLine()的阻塞问题。

case R.id.submit:
                //TODO 把数据提交的方式写在这里
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                String message1 = projName1.getText().toString();
                                try {
                                    socket = new Socket("192.168.3.50",777); //IP地址、端口号
                                    //向服务器发送消息
                                    out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8")), true);
                                    out.write(message1);
                                    out.flush();
                                    //接收服务器的消息
                                    br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
                                    String info = null;
                                    while ((info = br.readLine())!=null){
                                         projName1.setText(info);
                                    }
                                
                                    //关闭资源
                                    br.close();
                                    out.close();
                                    socket.close();
                                } catch (IOException e) {
                                 e.printStackTrace();
                                }
                            }
                        }).start();
                        break;
            }
        }

可以参考一下下面我之前写的,你看接受数据那一部分就行了


private ServerSocket mServerSocket;
private Socket mSocket;
private void openService() {
        try {
            mServerSocket = null;
            mServerSocket = new ServerSocket(5000);//端口号5000
        } catch (Exception e) {
            e.printStackTrace();
            log("服务开启失败");
            return;
        }
        log("服务开启成功");
        //启动服务线程
        SocketAcceptThread socketAcceptThread = new SocketAcceptThread();
        socketAcceptThread.start();
    }
  /**
     * 连接线程
     * 得到Socket
     */
    class SocketAcceptThread extends Thread {
        @Override
        public void run() {
            try {
                //等待客户端的连接,Accept会阻塞,直到建立连接,
                //所以需要放在子线程中运行
                mSocket = mServerSocket.accept();
                mServerSocket.close();//关键是这一步,当ServerSocket收到客户端连接之后,关闭ServerSocket
                //启动消息接收线程
                log("socket开启中");
                startReaderService(mSocket);
                log("socket开启成功");
            } catch (IOException e) {
                e.printStackTrace();
                log("socket开启失败");
            }
        }
    }
/**
     * 从参数的Socket里获取最新的消息
     */
    private void startReaderService(final Socket socket) {
        new Thread() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
//                        MsgInfo msgInfo = new MsgInfo(2, mServerIP, "开启成功");
//                        msgInfo.setCreatDate(System.currentTimeMillis());
//                        msgInfo.setCreatTime(getDateToString(msgInfo.getCreatDate()));
//                        mAdapter.addData(msgInfo);
                        mBinding.btSend.setEnabled(true);
                    }
                });
                DataInputStream reader;
                try {
                    // 获取读取流
                    reader = new DataInputStream(socket.getInputStream());
                    while (isOpenService) {
                        // 读取数据
                        String msg = reader.readUTF();
                        log("客户端的信息:" + msg);
                        //发消息更新UI
                        Message message = new Message();
                        message.what = 1;
                        message.obj = msg;
                        serviceHandler.sendMessage(message);
                        try {
                            SystemClock.sleep(100);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                } catch (Exception e) {
                    log("断开连接导致异常");
                    e.printStackTrace();
                    if (mSocket != null) {
                        try {
                            mSocket.close();
                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        } finally {
                            mSocket = null;
                        }
                        openService();//当前客户端断开连接之后,重新开启ServerSocket,等待连接
                    }
                }
            }
        }.start();
    }

更改为字节读取,不使用行读取。

readLine()在没有读取到换行时。是不会返回的。而是处于阻塞状态。

修改为字节读取,并且修改为available阻塞,这样的话,更加好一些

 private class ReadThread extends Thread {
        private final int serialPort;
        private boolean isStop = false;

        public ReadThread(int serialPort) {
            this.serialPort = serialPort;
        }

        public void stopRead() {
            isStop = true;
        }

        @Override
        public void run() {
            super.run();
            while (!isStop) {
                synchronized (mLock) {
                    try {
                        int count = inputStream.available();
                        if (count > 0) {
                            byte[] data = new byte[count];
                            inputStream.read(data);
                        }
                        //休眠10秒,防止空跑
                        sleep(10);
                    } catch (Exception e) {
                        e.printStackTrace();
                        LogUtils.e(TAG, "receiver data exception " + e.toString());
                    }
                }
            }

        }
    }