2016-09-29 32 views
0

我按照developer.android.com中的說明進行網絡調用(使用HttpURLConnection)。現在,我收到了內存不足異常,應用程序崩潰。HttpURLConnection拋出OutMemoryError

以下是堆棧跟蹤:

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 
    Process: com.example.app, PID: 19869 
    java.lang.RuntimeException: An error occurred while executing doInBackground() 
    at android.os.AsyncTask$3.done(AsyncTask.java:318) 
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) 
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 
    Caused by: java.lang.OutOfMemoryError: Failed to allocate a 4294967306 byte allocation with 4056144 free bytes and 370MB until OOM 
    at com.example.app.webservices.HttpConnectionClass.readIt(HttpConnectionClass.java:158) 
    at com.example.app.webservices.HttpConnectionClass.downloadUrl(HttpConnectionClass.java:123) 
    at com.example.app.webservices.HttpConnectionClass.access$100(HttpConnectionClass.java:28) 
    at com.example.app.webservices.HttpConnectionClass$DownloadWebpageTask.doInBackground(HttpConnectionClass.java:52) 
    at com.example.app.webservices.HttpConnectionClass$DownloadWebpageTask.doInBackground(HttpConnectionClass.java:46) 
    at android.os.AsyncTask$2.call(AsyncTask.java:304) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)  
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)  
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)  
    at java.lang.Thread.run(Thread.java:761)  

我已經包括這在我的清單:

android:largeHeap="true" 

這是我Networkclass:

public class HttpConnectionClass { 

    public static Activity context; 

    List json; 
    static boolean dialogIsShowing = true; 
    public String url; 
    List<NameValuePair> params = new ArrayList<NameValuePair>(); 
    public void getPostResponse_WithAsyn(Activity context, String url, List json, String message) { 
     this.params = json; 
     this.url= url; 
     this.json = json; 
     Log.v("TAG","PARAMS::"+json.toString()); 
     //add all the default parameters here 
     new DownloadWebpageTask().execute(url); 
    } 

    private class DownloadWebpageTask extends AsyncTask<String, Void, String> { 
     @Override 
     protected String doInBackground(String... urls) { 
      // params comes from the execute() call: params[0] is the url. 
      try { 
       return downloadUrl(urls[0]); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       return "Unable to retrieve web page. URL may be invalid."; 
      } 
     } 
     // onPostExecute displays the results of the AsyncTask. 
     @Override 
     protected void onPostExecute(String result) { 

      GetHttpPostResponse.myJsonResponse = result; 

      /*int maxLogSize = 1000; 
      for(int i = 0; i <= result.length()/maxLogSize; i++) { 
       int start = i * maxLogSize; 
       int end = (i+1) * maxLogSize; 
       end = end > result.length() ? result.length() : end; 
       Log.v("TAG_result", result.substring(start, end)); 
      } 
      */ 
      Log.v("Connection class","Response::"+result); 
     } 
    } 

    private String downloadUrl(String myurl) throws IOException { 
     InputStream is = null; 
     // Only display the first 500 characters of the retrieved 
     // web page content. 
     int len =Integer.MAX_VALUE; 

     try { 
      URL url = new URL(myurl); 
      HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
      Log.v("TAG","CONNECTING URL::"+myurl); 
      conn.setReadTimeout(10000 /* milliseconds */); 
      conn.setConnectTimeout(15000 /* milliseconds */); 
      conn.setRequestMethod("POST"); 
      conn.setDoInput(true); 
      conn.setDoOutput(true); 

      List<NameValuePair> params = new ArrayList<NameValuePair>(); 
      params.add(new BasicNameValuePair("key1", "")); 
      params.add(new BasicNameValuePair("key2", "")); 

      Log.v("TAG","PARAMETERS::"+params.toString()); 
      OutputStream os = conn.getOutputStream(); 
      BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8")); 
      writer.write(getQuery(params)); 
      writer.flush(); 
      writer.close(); 
      os.close(); 

      // Starts the query 
      conn.connect(); 

      int response = conn.getResponseCode(); 
      String res_data = conn.getResponseMessage(); 
      Log.d("TAG", "The response is: " + res_data); 
      is = conn.getInputStream(); 

      // Convert the InputStream into a string 
      String contentAsString = readIt(is, len); 
      return contentAsString; 

      // Makes sure that the InputStream is closed after the app is 
      // finished using it. 
     } finally { 
      if (is != null) { 
       is.close(); 
      } 
     } 
    } 

    private String getQuery(List<NameValuePair> params) throws IOException,UnsupportedEncodingException { 
     StringBuilder result = new StringBuilder(); 
     boolean first = true; 

     for (NameValuePair pair : params) { 
      if (first) 
       first = false; 
      else 
       result.append("&"); 

      result.append(URLEncoder.encode(pair.getName(), "UTF-8")); 
      result.append("="); 
      result.append(URLEncoder.encode(pair.getValue(), "UTF-8")); 
     } 

     return result.toString(); 
    } 
    public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException { 
     Reader reader = null; 
     reader = new InputStreamReader(stream, "UTF-8"); 
     char[] buffer = new char[len]; 
     reader.read(buffer); 
     return new String(buffer); 
    } 
} 

而且,我已經確認「len」是問題,並試圖對其進行硬編碼,但似乎並不適用於所有情況。

{"ResponseCode":"-1000","ResponseDesc":"Invalid user type."}� 

請幫我一把。

回答

1

試試這個方法readIt

public String readIt(InputStream stream) throws IOException, UnsupportedEncodingException { 
    StringBuffer sb = new StringBuffer(); 
    BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8")); 
    String line; 
    while ((line = br.readLine()) != null){ 
     sb.append(line); 
    } 
    br.close(); 
    return sb.toString(); 
} 
+0

謝謝,它工作。 –

0

你正在嘗試做的

int len =Integer.MAX_VALUE; 
char[] buffer = new char[len]; 

你有那麼多的記憶?

+0

感謝您快速reply.Yes,我從服務器獲取數據巨大的 –

+0

但你是在Android上,即使你不是我確定默認堆大小不會設置爲這麼多內存 –

+0

讀取錯誤 - *無法分配4294967306字節分配與4056144空閒字節* –

0

您正在分配長度爲Integer.MAX_LENGTH的char數組,它不適合可用內存。我想你會更好的有readIt()是這個樣子:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
byte[] buffer = new byte[1024]; 
int l; 
while ((l = stream.read(buffer)) != -1) { 
    baos.write(buffer, 0, l); 
} 
return baos.toString("UTF-8"); 
+0

你好,感謝你的快速回復,是的,我試過了,但我得到了問題,我的答案使解析困難。像這樣:{「ResponseCode」:「 - 1000」,「ResponseDesc」:「無效的用戶類型。」} –

+0

使用非UTF-8編碼的響應是否被編碼? – Petter

+0

不,只使用UTF-8。 –

相關問題