2013-10-01 88 views
3

我在asynctask中出現內存不足錯誤,它循環到stringbuilder。我使用該下載下面我SD card.My代碼中從服務器和存儲圖像的目標:StringBuilder追加原因內存不足

HttpClient httpclient = new DefaultHttpClient(); 
     httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); 
     HttpPost httppost = new HttpPost(severPath);   

     httppost.setEntity(params[0]); 
     System.out.println("executing request " + httppost.getRequestLine()); 



      HttpResponse response = null; 
      try { 
       response = httpclient.execute(httppost); 
      } catch (ClientProtocolException e6) { 
       // TODO Auto-generated catch block 
       e6.printStackTrace(); 
      } catch (IOException e6) { 
       // TODO Auto-generated catch block 
       e6.printStackTrace(); 
      } 
      String output; 
      System.out.println("Output from Server .... \n"); 

      BufferedReader br = null; 
      try { 
       br = new BufferedReader(
         new InputStreamReader((response.getEntity().getContent()))); 
      } catch (IllegalStateException e5) { 
       // TODO Auto-generated catch block 
       e5.printStackTrace(); 
      } catch (IOException e5) { 
       // TODO Auto-generated catch block 
       e5.printStackTrace(); 
      } 

      OutputStreamWriter outputStreamWriter = null; 
      try { 
       outputStreamWriter = new OutputStreamWriter(context.openFileOutput("LargeImages.txt", context.MODE_PRIVATE)); 
      } catch (FileNotFoundException e6) { 
       // TODO Auto-generated catch block 
       e6.printStackTrace(); 
      } 
      int i = 0; 


      StringBuilder builder = new StringBuilder(); 


      String Result = ""; 
       try { 
        for (String line = null; (line = br.readLine()) != null ;) { 
             builder.append(line.toString()); 

        } 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 




        outputStreamWriter.close(); 

我得到了內存分配錯誤的。請幫忙。我嘗試了很多方法,但也沒有得到正確的答案。

+0

循環迭代多少次? –

+0

是您的for循環在沒有更多行可用後正確終止? –

+0

你幾乎可以擴展你的代碼嗎? –

回答

0

如果您正在下載圖片,那麼您不應該使用Reader/Writer/StringBuilder來存儲它的內容。由於該文件是二進制內容將被加擾,因爲Reader/Writer類使用character encoding

嘗試使用InputStream/OutputStream並將內容直接存儲到SD卡而不將其存儲在內存中。

試試下面的代碼:

InputStream in = response.getEntity().getContent(); 
OutputStream out = context.openFileOutput("LargeImages.txt", context.MODE_PRIVATE); 
byte b[] = new byte[4096]; 
int i; 
while ((i = in.read(b)) >= 0) { 
    out.write(b, 0, i); 
} 
+0

這是什麼樣的? – nick

+0

@nick,我剛添加它。 – Claudiu

0

可能有兩個問題。 第一個 - 週期for (String line = null; (line = br.readLine()) != null ;)未正確終止。嘗試通過打開一個小文件(例如總共10行)找出它。

第二個 - 它實際上是一個內存不足的情況。可能這不是通過字符串獲取圖像的最佳方法,因爲圖像可能非常沉重,創建大量字符串會導致自然記憶錯誤。嘗試找到另一種方法。

0

我不認爲這是實際寫入到輸出流的代碼。在收盤前不應該有一條線,就像outputStreamWriter.print(builder)

關於你的問題。不要在StringBuilder中將所有數據收集到內存中,而是一次性寫入內存,而應該直接在for循環中寫入每行代碼。你根本不需要StringBuilder。這裏有一個代碼片段:

  try { 
       for (String line = br.readLine(); line != null; line = br.readLine()) { 
        outputStreamWriter.append(line); 
       } 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
       return; 
      } 

三個以上的言論:

  • 當你得到一個異常,你也應該停止動作,例如從你的方法返回。你上面的代碼會打印Stacktrace(這肯定是有用的),但會繼續,這不會很有幫助。只需在每個printstackTrace後添加return即可。
  • 仍然有可能一條線的記憶太長,但風險最小。
  • 是您下載的二進制圖像或文本的數據?您將其命名爲圖像,但您下載了文本。請注意,字節和字符之間存在差異(用字符集編碼)並保持在實際接收的範圍內。