2012-05-09 66 views
1

即時通訊使用此代碼時,得到一個內存不足的異常:內存不足上的AsyncTask在Android中

 class ApiTask extends AsyncTask<URI, Void, String> { 

    private Exception exception; 

    protected void onPreExecute() { 
     dialog = ProgressDialog.show(DownloadedActivity.this, "", 
       "Contacting Server...", true); 
    } 

    protected String doInBackground(URI... uri) { 
     try { 

      HttpClient client = new DefaultHttpClient(); 
      HttpGet request = new HttpGet(); 
      try { 
       request.setURI(uri[0]); 
       return client.execute(request, new BasicResponseHandler()); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

      return "Error"; 

     } catch (Exception e) { 
      this.exception = e; 
      return "Error"; 
     } 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     dialog.dismiss(); 
     processJSON(result); 
     updateListView(); 
     result = null; 
     System.gc(); 
      } 
      } 

錯誤發生時,我在刷新方法運行此代碼第二次,這讓我懷疑有內存泄漏。響應是一個很大的JSON對象。我希望找出我做錯了什麼,我嘗試了一些東西,但它看起來像響應保留在內存中。

這裏是logcat的錯誤:

05-09 13:45:13.764: E/AndroidRuntime(2438): Uncaught handler: thread AsyncTask #2 exiting due to uncaught exception 
05-09 13:45:13.784: E/AndroidRuntime(2438): java.lang.RuntimeException: An error occured while executing doInBackground() 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at android.os.AsyncTask$3.done(AsyncTask.java:200) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.lang.Thread.run(Thread.java:1096) 
05-09 13:45:13.784: E/AndroidRuntime(2438): Caused by: java.lang.OutOfMemoryError 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.lang.String.<init>(String.java:513) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at org.apache.http.util.CharArrayBuffer.toString(CharArrayBuffer.java:261) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at org.apache.http.util.EntityUtils.toString(EntityUtils.java:141) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at org.apache.http.util.EntityUtils.toString(EntityUtils.java:146) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:76) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:59) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:657) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:627) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:616) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at com.nelissen.couchforwarder.couch.DownloadedActivity$ApiTask.doInBackground(DownloadedActivity.java:382) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at com.nelissen.couchforwarder.couch.DownloadedActivity$ApiTask.doInBackground(DownloadedActivity.java:1) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
05-09 13:45:13.784: E/AndroidRuntime(2438):  ... 4 more 
+0

請提供你的'processJSON'方法的代碼 - 如果在那裏有什麼可疑的東西,它很容易進入無限遞歸。 –

+0

請求返回的字符串大小約爲6MB,我認爲問題在那裏。當OutOfMemory錯誤出現時,甚至不會調用processJson。哦,我忘了添加錯誤只發生在24mb堆大小的設備上。如果不處理時檢查它是否崩潰。 – Boris

+0

它在AsyncTask上崩潰而不是處理,我通過刪除解析來檢查。我添加了logcat – Boris

回答

0

我相信這是發生由於你已經寫在你的代碼中的一句話:

return client.execute(request, new BasicResponseHandler()); // inside doInBackground 

我建議你創建另一個的AsyncTask的相同並在onPostExecute()方法內執行這個新的AsyncTask。

而另一個可能是由於processJSON(result);,它可能是一個耗時的過程。

+0

我不明白爲什麼這會解決問題? – Boris

1

我發現AsyncTask和Activity有點「鬆散地綁在一起」,所以也許這個AsyncTask並不完全是.DIE!哈哈:d

嘗試讀取這個鏈接:Android AsyncTask for Long Running Operations

反正在我的代碼onRefresh我殺了他們兩個!

public void onRefresh(View view){ // this is a method inside the Activity about to be killed    
    downloadXmlTaskObject = null; // Garbage Collectible 
    finish();    // Finish the Activity 
    Intent intent = getIntent(); // get the intent of the Activity 
    startActivity(intent); // and Create a new Activity   
} 

我不知道但如果它符合您的要求或不..你可以只用於下載或分析等,然後殺了他們兩個的目的創建活動! 祝你好運!^_^