我有一个名为RetreiveHttpStringResponse
的班级。它用于从包含JSON数据的URL中获取InputStream
。该课程延伸AsyncTask<String, Void, InputStream>
。所以这里奇怪的问题是总是返回null。无论。甚至没有例外。我使用调试器检查了程序行为,并且可以看到在第(1)点,处理立即跳转到finally语句并继续return null;
。并且再次没有错误,也没有例外。该程序正常运行。
我使用的是Android 4.4(SDK版本19),响应代码为200,并且在Manifest文件中设置了以下行。
问题出现在模拟器和具有互联网连接的真实设备上。这是代码:
@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;
被完全忽略。我用调试器检查了String中的数据,这是正确的!没有错误没有例外。
答案 0 :(得分:1)
finally
将在任何一种情况下运行,也会在正常返回期间运行,无异常。然后在close
语句子句中调用。finally
。
因此,您的代码始终返回已关闭的流。可能这不是你想要的。
你的描述(“跳转到finally语句”)仍然看起来非常像urlConn.getInputStream()
引发的异常。奇怪你没有观察到它。
答案 1 :(得分:0)
我不明白为什么你得到你的空结果但是,你做错了一件事实际上是回归InputStream
:
is= urlConn.getInputStream(); //-->(1)<--
return is;
你应该在doInBackground
(在工作线程上)读取你的流,否则在onPostExecute(UI线程)中读取它可能会导致NetworkOnMainThreadException
,或者至少是ANR。从InputStream读取数据仍然是网络操作 - 您下载的数据可能是几MB。