2

我有一個叫做RetreiveHttpStringResponse的類。它用於從包含JSON數據的URL獲取InputStream。該課程延伸AsyncTask<String, Void, InputStream>。所以這裏的奇怪問題是總是返回null。無論。甚至沒有例外。我用調試器檢查了程序的行爲,並可以看到在第(1)點處理立即跳轉到finally語句並繼續使用return null;。並且沒有錯誤,也沒有例外。該程序正常運行。 我正在使用Android 4.4(SDK版本19),響應代碼爲200,在Manifest文件中設置了以下行。android-在try語句中忽略返回

  • 使用許可權的android:NAME = 「android.permission.INTERNET對」
  • 使用許可權的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;完全被忽略。我用調試器檢查了字符串中的數據,它是正確的!沒有錯誤沒有例外。

+0

你確定在輸入流中有東西可以得到嗎?要獲得不爲null,您可以簡單地初始化您的 is = new InputStream();然後只在ulrConn.getInputStream()!= null :)時分配給你的'is'變量[首先初始化]。 – RMachnik

+0

問題是程序跳到返回null;而忽略了回報;完全。即使沒有輸入流,它仍然沒有被返回。 – user2988551

+0

它不能做到這一點,或者只是你得到一個異常,而不是在代碼中的任何catch子句中捕獲它。但它也不能跳轉到'返回null'行。 – RMachnik

回答

0

我不明白爲什麼你得到你空的結果,但是,有一件事你做錯了真的返回InputStream

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

你應該閱讀doInBackground您的數據流(在工作線程),否則,閱讀它onPostExecute(UI線程),可能會導致NetworkOnMainThreadException或至少ANR。從InputStream中讀取數據仍然是一項網絡操作 - 您下載的數據可能爲幾個MB。

+0

謝謝,但讀數是在doInBackround方法中完成的。還是我錯了? – user2988551

+0

從你的代碼中,我沒有看到你已經從你的InputStream – marcinj

+0

讀什麼也,你正在返回的InputStream,但最終也關閉它(讀AudriusMeškauskas答案),所以你會在onPostExecute得到封閉的InputStream。 – marcinj

1

finally將在任一情況下運行,也在正常返回期間沒有例外。你打電話。 closefinally聲明子句中。

所以你的代碼總是返回封閉的流。可能這不是你想要的。

您的描述(「跳轉到最後聲明」)仍然看起來非常像urlConn.getInputStream()引發的異常。奇怪你不會觀察它。

+0

謝謝。我終於知道了,但是你的意思是我不應該關閉我的輸入流?是的,我看不到任何例外。程序的其餘部分仍在繼續。 – user2988551

+0

您現在編輯了代碼以返回字符串而不是輸入流,因此這不再相關。 – h22