HttpURLConnection.getInputStream()挂起,永远不会完成

时间:2018-04-17 16:36:21

标签: 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) {
        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中的Network面板时,请求说它没有传回任何东西。但是,在浏览器中访问JSON端点可以正确地恢复所有内容。

希望有人知道问题可能是什么。我试图谷歌的东西无济于事。如果需要更多信息,请与我们联系。感谢。

4 个答案:

答案 0 :(得分: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)GET:

invokeHTTPRequest(url, "GET", headers, null);

b)POST

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
    }

}

答案 1 :(得分:3)

InputStream inputStream = httpURLConnection.getInputStream();从未完成,因为它正在抛出java.security.cert.CertPathValidatorException。错误没有被记录,因为我没有在我的try / catch块中捕获此类错误。

答案 2 :(得分:2)

您忘记在connect上致电HttpUrlConnection

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

答案 3 :(得分:1)

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

 HttpURLConnection conn = ...
 conn.setConnectTimeout(5000);
 conn.setReadTimeout(5000);

默认情况下,超时设置为0,按照setConnectTimeout(),这意味着:

  

超时为零被解释为无限超时。