Java HttpURLConnection.getInputStream()挂起并且永远不会完成

Java HttpURLConnection.getInputStream()挂起并且永远不会完成,java,android,android-studio,android-asynctask,Java,Android,Android Studio,Android Asynctask,我正在尝试使用以下代码从JSON端点获取令牌: public class FetchToken extends AsyncTask<String, Void, Void> { String data = ""; String token = ""; public TokenDelegate delegate = null; @Override protected Void doInBackground(String... identity)

我正在尝试使用以下代码从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);
    }
}
公共类FetchToken扩展异步任务{
字符串数据=”;
字符串标记=”;
public-TokenDelegate-delegate=null;
@凌驾
受保护的Void doInBackground(字符串…标识){
试一试{
if(identity.length==1){
URL=新URL(标识[0]);
HttpURLConnection HttpURLConnection=(HttpURLConnection)url.openConnection();
InputStream InputStream=httpURLConnection.getInputStream();
BufferedReader BufferedReader=新的BufferedReader(新的InputStreamReader(inputStream));
字符串行=”;
while(行!=null){
line=bufferedReader.readLine();
数据=数据+行;
}
JSONObject JO=新的JSONObject(数据);
token=JO.get(“token”).toString();
}
}捕获(格式错误){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}捕获(JSONException e){
e、 printStackTrace();
}
返回null;
}
@凌驾
受保护的void onPostExecute(void避免){
Log.d(“令牌”,令牌);
//delegate.processFinish(令牌);
super.onPostExecute(避免);
}
}
我已经尝试在每一行之后打印到调试日志,似乎这一行
InputStream InputStream=httpURLConnection.getInputStream()永远不会完成,其余的代码也不会执行。然而,这是在一个异步任务内部发生的,并且该异步任务的onPostExecute方法正在启动,就好像任务已经完成一样,而它看起来并不像已经完成一样

似乎没有执行任何catch块,当我检查Android Profiler中的网络面板时,请求说它没有返回任何内容。然而,在浏览器中访问JSON端点会使一切恢复正常


希望有人知道问题出在哪里。我试图用谷歌搜索东西,但没有用。如果需要更多信息,请告诉我。谢谢。

您很可能希望设置超时,以确保在外部资源不及时可用时连接失败。值以毫秒为单位,例如,连接和读取的5秒超时将为:

 HttpURLConnection conn = ...
 conn.setConnectTimeout(5000);
 conn.setReadTimeout(5000);
默认情况下,超时设置为
0
,根据
setConnectTimeout()
这意味着:

零超时被解释为无限超时


您忘记在
HttpUrlConnection
上调用
connect

HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();

看看下面的代码,并相应地修改您的代码

1) 若方法是GET,那个么数据或头可以为null

示例用法

 url = <some url>
 Map<String, String> headers = new HashMap<String, String>();       
 headers.put("Content-Type", "application/json");       
 headers.put("Accept", "application/json");
b) 职位

公共静态字符串invokeHTTPRequest(字符串urlString、字符串方法、映射头、字符串数据){

URL=null;
试一试{
url=新url(url字符串);
HttpURLConnection conn=null;
conn=(HttpURLConnection)url.openConnection();
conn.setRequestMethod(方法);
连接设置连接超时(10000);
连接设置读取超时(10000);
如果(标题!=null){
for(Map.Entry头:headers.entrySet()){
conn.setRequestProperty(header.getKey(),header.getValue());
}
}
如果(数据!=null){
字节[]postDataBytes=data.toString().getBytes();
conn.setRequestProperty(“内容长度”,String.valueOf(postDataBytes.Length));
连接设置输出(真);
conn.getOutputStream().write(postDataBytes);
}
BufferedReader rd=null;
如果(连接getResponseCode()==200){
rd=新的BufferedReader(新的InputStreamReader(conn.getInputStream());
}
否则{
rd=新的BufferedReader(新的InputStreamReader(conn.getErrorStream());
}
StringBuilder结果=新建StringBuilder();
弦线;
而((line=rd.readLine())!=null){
结果。追加(行);
}
rd.close();
返回result.toString();
}捕获(例外e){
//在这里处理异常
}
}

InputStream-InputStream=httpURLConnection.getInputStream()
从未完成,因为它引发了
java.security.cert.CertPathValidatorException
。没有记录错误,因为我没有在try/catch块中捕获此类错误。

使用.connect()添加行似乎无法解决问题。实际上,不需要使用
connect()
。只需调用
url.openConnection()即可是的,我忘了getInputStream()会强制连接():/谢谢你的建议。不幸的是,这并没有解决这个问题。当我在浏览器中访问资源时,它返回的速度确实快于超时时间。
该异步任务的onPostExecute方法正在启动
-然后
httpURLConnection.getInputStream()
正在工作,如果
(identity.length==1)
,因为这是一个阻塞调用,您确定没有捕获异常并返回
null
-检查日志猫吗?还要确保关闭
最后
块中的流您是否找到了正确的解决方案?在我的例子中,这是因为我的模拟器无法连接到internet
invokeHTTPRequest(url, "GET", headers, null);
Student st = new Student();
Gson gson = new Gson();
String jsonReqData = gson.toJson(st);
String resp = invokeHTTPRequest3(url, "POST", headers,  jsonReqData);
    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
    }

}