HttpURLConnection.getInputStream() 挂起并且永远不会完成
Posted
技术标签:
【中文标题】HttpURLConnection.getInputStream() 挂起并且永远不会完成【英文标题】:HttpURLConnection.getInputStream() hangs and never finishes 【发布时间】:2018-09-27 17:27:43 【问题描述】:我正在尝试使用以下代码从 JSON 端点获取令牌:
public class FetchToken extends AsyncTask<String, Void, Void>
String data = "";
String token = "";
public TokenDelegate delegate = null;
@Override
protected Void doInBackground(String... identity)
try
if (identity.length == 1)
URL url = new URL(identity[0]);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while (line != null)
line = bufferedReader.readLine();
data = data + line;
JSONObject JO = new JSONObject(data);
token = JO.get("token").toString();
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (JSONException e)
e.printStackTrace();
return null;
@Override
protected void onPostExecute(Void aVoid)
Log.d("token", token);
//delegate.processFinish(token);
super.onPostExecute(aVoid);
我尝试在每一行之后打印到调试日志,似乎InputStream inputStream = httpURLConnection.getInputStream();
行永远不会完成,其余代码也不会执行。但是,这发生在 AsyncTask 内部,并且该 AsyncTask 的 onPostExecute 方法正在触发,就好像任务已经完成一样,但它看起来好像已经完成了。
似乎没有执行任何 catch 块,当我检查 android Profiler 中的网络面板时,请求说它没有传回任何东西。但是,在浏览器中访问 JSON 端点会使一切恢复正常。
希望有人知道问题可能是什么。我试图用谷歌搜索无济于事。如果需要更多信息,请告诉我。谢谢。
【问题讨论】:
the onPostExecute method of that AsyncTask is firing
- 那么httpURLConnection.getInputStream()
正在工作,如果(identity.length == 1)
因为这是一个阻塞调用,你确定你没有捕获异常并返回null
- 检查logcat ?还要确保关闭 finally
块中的流
你找到正确的解决方案了吗?
就我而言,这是因为我的模拟器无法连接到互联网
【参考方案1】:
您很可能希望设置超时以确保在外部资源无法及时获得时连接失败。这些值以毫秒为单位,例如连接和读取的 5 秒超时将是:
HttpURLConnection conn = ...
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
默认情况下,超时设置为0
,根据setConnectTimeout()
,这意味着:
零超时被解释为无限超时。
【讨论】:
感谢您的建议。不幸的是,这并没有解决问题。当我在浏览器中访问资源时,它确实比超时恢复得更快。【参考方案2】:InputStream inputStream = httpURLConnection.getInputStream();
行从未完成,因为它正在抛出 java.security.cert.CertPathValidatorException
。错误没有被记录,因为我没有在我的 try / catch 块中捕捉到这种类型的错误。
【讨论】:
【参考方案3】:查看下面的代码并相应地修改您的代码。
1) 如果方法是 GET,则数据或标头可以为空。
示例用法
url = <some url>
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
headers.put("Accept", "application/json");
a) 获取:
invokeHTTPRequest(url, "GET", headers, null);
b) 发布
Student st = new Student();
Gson gson = new Gson();
String jsonReqData = gson.toJson(st);
String resp = invokeHTTPRequest3(url, "POST", headers, jsonReqData);
public static String invokeHTTPRequest(String urlString, String method, Map headers,String data)
URL url = null;
try
url = new URL(urlString);
HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(method);
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
if (headers != null)
for (Map.Entry<String, String> header : headers.entrySet())
conn.setRequestProperty(header.getKey(), header.getValue());
if (data != null)
byte[] postDataBytes = data.toString().getBytes();
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
conn.getOutputStream().write(postDataBytes);
BufferedReader rd = null;
if(conn.getResponseCode() == 200)
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
else
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = rd.readLine()) != null)
result.append(line);
rd.close();
return result.toString();
catch (Exception e)
//handle exception here
【讨论】:
【参考方案4】:您忘记在HttpUrlConnection
上拨打connect
:
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
【讨论】:
用 .connect() 添加行似乎不能解决问题。 其实connect()
是不需要的。只需调用url.openConnection();
就足够了
是的,我忘了 getInputStream() 会强制 connect() :/以上是关于HttpURLConnection.getInputStream() 挂起并且永远不会完成的主要内容,如果未能解决你的问题,请参考以下文章