异步任务,缓冲读取器



我有一个缓冲阅读器,当我尝试读取它时,它只是挂起并且不做任何事情,我这样做对吗?我正在AsyncTask中使用它。

  • 编辑:我有一个平板电脑连接到Wi-Fi,它连接到我的计算机,该计算机在端口172.20.104.203上广播5334,我可以看到线程何时启动,但之后什么都没有。

这是我的代码:

try {
       final BufferedReader in = new BufferedReader(
       new InputStreamReader(socket.getInputStream()));       
       String line = null;
       while ((line = in.readLine()) != null) {
          final String msg;
          msg = (line);
          Log.d("DeviceActivity", msg);
       }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("ClientAcivtity: Exception",
        String.valueOf(e));
    }
  • 编辑我拥有所有正确的权限或任何东西,我在 AsyncTask 之外执行此操作,它运行良好,移动了它,因为我不想让它在主线程中。

-编辑,这是完整的代码。

public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
        Socket nsocket; // Network Socket
        InputStream nis; // Network Input Stream
        OutputStream nos; // Network Output Stream
        private Handler handler = new Handler();
        Boolean connected = false;
        public static final int PORT = 5334;
        public String SERVERIP = "172.20.104.203";
        Socket socket;
        @Override
        protected void onPreExecute() {
            Log.i("AsyncTask", "onPreExecute");
            InetAddress serverAddr;
            try {
                serverAddr = InetAddress.getByName(SERVERIP);
                socket = new Socket(serverAddr, PORT);
                connected = true;
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                Log.e("ClientAcivtity: Exception", String.valueOf(e));
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                Log.e("ClientAcivtity: Exception", String.valueOf(e));
            }
        }
        @Override
        protected Boolean doInBackground(Void... params) { // This runs on a
                                                            // different thread
            boolean result = false;
            try {
                Log.d("ClientActivity", "C: Connecting...");
                if (socket != null) {
                    int cont = 1;
                    while (cont == 1) {
                        try {
                            Log.d("ClientActivity", "C: Sending command.");
                            PrintWriter out = new PrintWriter(
                                    new BufferedWriter(new OutputStreamWriter(
                                            socket.getOutputStream())), true);
                            // where you issue the commands
                            out.println("getPos");
                            Log.d("ClientActivity", "C: Sent " + "getPos");
                        } catch (Exception e) {
                            Log.e("ClientAcivtity: Exception",
                                    String.valueOf(e));
                        }
                        try {
                            final BufferedReader in = new BufferedReader(
                                    new InputStreamReader(
                                            socket.getInputStream()));
                            String line = null;
                            while ((line = in.readLine()) != null) {
                                final String msg;
                                msg = (line);
                                Log.d("DeviceActivity", msg);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            Log.e("ClientAcivtity: Exception",
                                    String.valueOf(e));
                        }
                        cont--;
                    }
                    Log.d("ClientActivity", "C: Closed.");
                }
            } catch (Exception e) {
                Log.e("ClientAcivtity: Exception", String.valueOf(e));
            }
            return result;
        }
        @Override
        protected void onProgressUpdate(byte[]... values) {
            if (values.length > 0) {
                Log.i("AsyncTask", "onProgressUpdate: " + values[0].length
                        + " bytes received.");
            }
        }
        @Override
        protected void onCancelled() {
            Log.i("AsyncTask", "Cancelled.");
        }
        @Override
        protected void onPostExecute(Boolean result) {
            if (socket != null) {
                if (connected) {
                    if (result) {
                        Log.i("AsyncTask",
                                "onPostExecute: Completed with an Error.");
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    } else {
                        Log.i("AsyncTask", "onPostExecute: Completed.");
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

我的猜测是,当你写出命令"getPos"时,底层的BufferedWriter实际上并没有在线上发送数据(你应该用tcpdump/wireshark验证这一点)。如果是这种情况,服务器不会响应 readLine(),因为它从未收到命令。要验证此声明,请在out.println("getPos");后添加out.flush();

真的,tcpdump 可能会给你一个比论坛上任何人更好的答案。

另请参阅 http://developer.android.com/reference/java/io/BufferedWriter.html

尝试这样做:

final BufferedReader in = new BufferedReader(new InputStreamReader(
                                                    socket.getInputStream()));
StringBuffer buf = new StringBuffer();
int i;
while((i = in.read()) != -1){
    buf.append((char) i);
}
String data = buf.toString();

从套接字读取是一个相当困难的问题,具体取决于套接字实际连接到的位置以及另一端的响应方式。

如果另一端非常快,则它可以为套接字提供足够的数据,以便读取例程实际上可以正常工作。但是,如果另一端存在任何类型的延迟(只需要比您的读取例程慢,包括小的默认超时),那么即使另一端可能有数据,您的读取也会失败 - 只是到达套接字有点太慢了。

根据您的需要,您可以围绕读取例程包装自己的最小和最大计时器。

请提供更多信息,我们可以更好地了解问题。

在许多情况下,有必要有一个足够大的最小超时,以便另一端将数据推送到套接字 - 但您可能还需要一个最长的时间来处理您实际想要等待数据到达的时间。

更新:

首先是可运行启动监视线程。如果需要,您可以使用循环中的monitoringCanRun来中断线程。monitoringThreadIsAlive可以用来知道线程是否仍在运行。

    monitoringCanRun = true;
    new Thread(new Runnable() {
    public void run() {
        monitoringThreadIsAlive = true;
        performMonitoring();
        monitoringThreadIsAlive = false;
    }
    }).start();
}

和 执行监控 如下所示:

   public void performMonitoring() {
while (monitoringCanRun) {
   ... do your read in the while loop
    ...you might like to insert some delay before trying again...
    try { //we delay every partial read so we are not too fast for the other side
    Thread.sleep(100);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
}
}