连接强制断开时,BufferedReader.readLine()挂起

时间:2014-10-19 13:02:55

标签: java android

我不断从网络服务获取数据。

URLConnection connection;
    BufferedReader in = null;

    try {
        SharedPreferences preferences = context.getSharedPreferences(
                "MyPreferences", Context.MODE_PRIVATE);
        int timeoutConnection = Integer.parseInt(preferences.getString(
                "timeout", "60")) * 1000;
        URL urlAddress = new URL(preferences.getString("apiUrl",
                defaultURL));
        connection = urlAddress.openConnection();
        connection.setConnectTimeout(timeoutConnection);
        in = new BufferedReader(new InputStreamReader(
                connection.getInputStream()));
        final String[] inputLine = { null };
        int i=0;
        while (isOnline() && (inputLine[0] = in.readLine()) != null) {   // isOnline checks if connected to internet.
            ((Activity) context).runOnUiThread(new Runnable() {
                    public void run() {
                        callback.run(inputLine[0]);
                    }
                });
        }
    } catch (Exception e) {
        ..
        ..
    }  

这一切正常,直到我连接到互联网。但是一旦我强行断开连接,inputLine[0] = in.readLine()就没有响应。我没有任何例外。
那么如何检查两者之间的连接是否断开?仅使用readLine()或其他内容 注意:我看到很少有建议使用BufferedReader.ready()的解决方案。我也尝试了,但它总是返回false 请给我一个有效的解决方案 感谢

2 个答案:

答案 0 :(得分:4)

在连接上设置read timeout。如果数据包刚被丢弃,TCP可能需要很长时间来检测断开的连接。

    connection = urlAddress.openConnection();
    connection.setReadTimeout(10000); // 10 seconds
    connection.setConnectTimeout(timeoutConnection);

答案 1 :(得分:1)

我认为您需要使用.read(char[] cbuf, int off, int len)而不是.readLine(),并进行自己的线路处理。以下是BufferedReader.read方法的文档:

  

此方法实现Reader类的相应读取方法的常规协定。作为额外的便利,它尝试通过重复调用底层流的读取方法来读取尽可能多的字符。此迭代读取将继续,直到满足以下条件之一:

     
      
  • 已读取指定数量的字符
  •   
  • 基础流的read方法返回-1,表示文件结束,或
  •   
  • 基础流的ready方法返回false,表示进一步的输入请求将被阻止。
  •   
     

如果对基础流的第一次读取返回-1以指示文件结束,则此方法返回-1。否则,此方法返回实际读取的字符数。

(强调我的。)

看起来read似乎不会阻止,因为它会询问底层流是否有任何可用的东西。

但请记住,它可能不会返回您要求的任意数量的字符,甚至可能会返回0。

你仍然有一个问题,那就是如果它返回0,那么你不知道是因为连接已经丢失还是因为网络服务器还没有产生任何东西。