我有一个名为RetreiveHttpStringResponse
的类。它用于从包含JSON数据的URL中获取InputStream
。该类扩展了AsyncTask<String, Void, InputStream>
。所以这里的奇怪问题是总是返回null。不管怎样。甚至没有例外。我用调试器检查了程序行为,可以看到在第(1)点,处理立即跳到finally语句,并继续使用return null;
。程序运行正常。我使用的是Android 4.4(SDK版本19),响应代码为200,在Manifest文件中设置了以下行。
- 使用权限android:name="android.permission.INTERNET">
- 使用权限android:name="android.permission.ACCESS_NETWORK_STATE">
问题发生在模拟器和具有互联网连接的真实设备上。这是代码:
@Override
protected InputStream doInBackground(String... arg0) {
URL url = null;
InputStream is = null;
HttpURLConnection urlConn = null;
int responseCode = 0;
try {
url = new URL(arg0[0]);
urlConn = (HttpURLConnection) url.openConnection();
urlConn.setReadTimeout(10000);
urlConn.setConnectTimeout(15000);
urlConn.setRequestMethod("GET");
urlConn.connect();
responseCode = urlConn.getResponseCode();
Log.d("DataHandlerInternet:RESPONSE_CODE", "The response is: " + responseCode);
is= urlConn.getInputStream(); //-->(1)<--
return is;
}
catch ( MalformedURLException e ) { // new URL() went wrong!
//TODO error message. URL is not correct!
e.printStackTrace();
}
catch (SocketTimeoutException e) { // Timeout while connecting or holding connection to URL.
//TODO error message. Timeout happened!
e.printStackTrace();
}
catch ( IOException e ) { // openConnection() failed!
//TODO error message. Couldn't connect to URL!
e.printStackTrace();
}
catch( Exception e ) { // Any other Exception!
e.printStackTrace();
}
finally {
try { if(is != null) { is.close(); } } catch(Exception e) {e.printStackTrace();}
try { if(urlConn != null) { urlConn.disconnect(); } } catch(Exception e) {e.printStackTrace();}
}
return null;
}
一个糟糕的解决方案是删除finally语句。这不是解决这个问题的最佳方法。现在我更改了代码。我已经把读数放进去了,只返回字符串。
@Override
protected String doInBackground(String... arg0) {
URL url = null;
InputStream is = null;
HttpURLConnection urlConn = null;
int responseCode = 0;
try {
url = new URL(arg0[0]);
urlConn = (HttpURLConnection) url.openConnection();
urlConn.setReadTimeout(10000);
urlConn.setConnectTimeout(15000);
urlConn.setRequestMethod("GET");
urlConn.connect();
responseCode = urlConn.getResponseCode();
Log.d("DataHandlerInternet:RESPONSE_CODE", "The response is: " + responseCode);
is= urlConn.getInputStream();
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ( (line = br.readLine()) != null ) {
sb.append(line);
}
return sb.toString();
}
catch ( MalformedURLException e ) { // new URL() went wrong!
//TODO error message. URL is not correct!
e.printStackTrace();
}
catch (SocketTimeoutException e) { // Timeout while connecting or holding connection to URL.
//TODO error message. Timeout happened!
e.printStackTrace();
}
catch ( IOException e ) { // openConnection() failed!
//TODO error message. Couldn't connect to URL!
e.printStackTrace();
}
catch( Exception e ) { // Any other Exception!
e.printStackTrace();
}
finally {
try { if(is != null) { is.close(); } } catch(Exception e) {e.printStackTrace();}
try { if(urlConn != null) { urlConn.disconnect(); } } catch(Exception e) {e.printStackTrace();}
}
return null;
}
然而,在经历while循环之后,return line;
被完全忽略。我已经用调试器检查了字符串中的数据,它是正确的!没有错误没有例外。
finally
在任何一种情况下都将运行,在正常返回期间也会运行,没有异常。然后你打电话。finally
语句子句中的close
。
所以你的代码总是返回关闭的流。也许这不是你想要的。
您的描述("跳转到finally语句")看起来仍然非常像urlConn.getInputStream()
抛出的异常。奇怪的是你没有观察到。
我不明白为什么你会得到空结果,但有一件事你做错了,那就是实际返回InputStream
:
is= urlConn.getInputStream(); //-->(1)<--
return is;
您应该在doInBackground
(工作线程上)中读取流,否则在onPostExecute(UI线程)中读取它,可能会导致NetworkOnMainThreadException
,或者至少是ANR。从InputStream读取数据仍然是一项网络操作——您下载的数据可能是几个MB。