android - 在try-statement中返回忽略

时间:2014-02-11 10:08:03

标签: java android httpurlconnection disconnect try-catch-finally

我有一个名为RetreiveHttpStringResponse的班级。它用于从包含JSON数据的URL中获取InputStream。该课程延伸AsyncTask<String, Void, InputStream>。所以这里奇怪的问题是总是返回null。无论。甚至没有例外。我使用调试器检查了程序行为,并且可以看到在第(1)点,处理立即跳转到finally语句并继续return null;。并且再次没有错误,也没有例外。该程序正常运行。 我使用的是Android 4.4(SDK版本19),响应代码为200,并且在Manifest文件中设置了以下行。

  • uses-permission android:name =“android.permission.INTERNET”
  • uses-permission 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;被完全忽略。我用调试器检查了String中的数据,这是正确的!没有错误没有例外。

2 个答案:

答案 0 :(得分:1)

finally将在任何一种情况下运行,也会在正常返回期间运行,无异常。然后在close语句子句中调用。finally

因此,您的代码始终返回已关闭的流。可能这不是你想要的。

你的描述(“跳转到finally语句”)仍然看起来非常像urlConn.getInputStream()引发的异常。奇怪你没有观察到它。

答案 1 :(得分:0)

我不明白为什么你得到你的空结果但是,你做错了一件事实际上是回归InputStream

    is= urlConn.getInputStream(); //-->(1)<--
    return is;

你应该在doInBackground(在工作线程上)读取你的流,否则在onPostExecute(UI线程)中读取它可能会导致NetworkOnMainThreadException,或者至少是ANR。从InputStream读取数据仍然是网络操作 - 您下载的数据可能是几MB。