[英]java.io.InputStream will not throw IOException when Wifi connectivity is lost
我的Android应用程序中的一些代码遇到了一个问题,它从URL下载文件,这里是一段代码片段:
int bytesRead = 0;
final byte[] buffer = new byte[32 * 1024];
InputStream stream = httpUrlConnection.getInputStream();
try {
while ((bytesRead = stream.read(buffer)) > 0) {
Log.i("TAG", "Read from steam, Bytes Read: " + bytesRead);
}
} catch (IOException ex) {
//Recover from lost WIFI connection.
} finally {
stream.close();
}
如果WiFi连接丢失,我的应用程序依赖于InputStream.read()
来抛出IOException
。 如Java 8文档中所述, 如果输入流已关闭,或者发生某些其他I / O错误,则此方法应抛出IOException
。 在Android M中,这会立即发生,我的代码可以处理并从异常中恢复。 在Android N中,不会抛出此异常导致我的应用程序只是挂在read()
方法中,它永远不会突破它。 有没有其他人遇到这个问题并以不会破坏向后兼容性的方式解决它? 这是一个新的Android N bug吗?
如果连接断开,从套接字读取可以永久阻止。 您需要使用读取超时。
为了避免重新发明轮子并发现自己弄清楚这个和其他一些常见场景,我会使用像Volley这样的高级库
请参阅: 使用Volley传输网络数据
Volley以非常直接的方式为您提供有趣的事物:
发送请求就像这样简单 (来自文档)
final TextView mTextView = (TextView) findViewById(R.id.text);
...
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Display the first 500 characters of the response string.
mTextView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
mTextView.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
设置超时/重试策略非常简单:
stringRequest.setRetryPolicy(new DefaultRetryPolicy(20 * 1000, 1, 1.0f));
参数是:
关于错误处理
如您所见,您正在向请求传递一个错误侦听器new Response.ErrorListener()
。 当出现错误时,Volley调用onErrorResponse回调public void onErrorResponse
方法在执行请求时发生错误时传递VolleyError对象的实例。
以下是凌空的例外列表,从这个帖子采取这里
所以你可以做的事情
if ((error instanceof NetworkError) || (error instanceof NoConnectionError)) {
//then it was a network error
}
正如@EJP所说“如果连接断开,从套接字读取可以永久阻塞”,只需将此行添加到代码中,并捕获java.net.SocketTimeoutException:
int bytesRead = 0;
final byte[] buffer = new byte[32 * 1024];
InputStream stream = httpUrlConnection.getInputStream();
httpUrlConnection.setConnectTimeout(5000);
try {
while ((bytesRead = stream.read(buffer)) > 0) {
Log.i("TAG", "Read from steam, Bytes Read: " + bytesRead);
}
} catch (java.net.SocketTimeoutException ex) {
//Recover from lost WIFI connection.
} finally {
stream.close();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.