簡體   English   中英

Android AsyncTask通過http請求內存不足

[英]Android AsyncTask out of memory via http request

所以基本上,讓我設置場景:

List<Account> accounts = ...//Initialised with 2 accounts.

for( Account ac : accounts)
{
   new AsyncTask<...>(){ getTwitterTimeLine(amount);}.execute();
}

所以你可以在這里看到兩個AsyncTasks直接調用另一個。

現在這里是有趣的部分,

如果我將amount變量設置為10.該方法調用HTTP請求,請求10個最新的feed項。 這非常正常,正常的行為比將返回的數據放入多個可能的列表視圖之一(所有這些都可以通過viewpager查看,因此在這種情況下2個列表視圖分別由2個異步任務填充)

如果我把金額加到100,那么基本上更多的JSON數據,我得到以下內容;

   04-04 03:11:20.175: E/AndroidRuntime(4574): FATAL EXCEPTION: AsyncTask #1
04-04 03:11:20.175: E/AndroidRuntime(4574):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.lang.Thread.run(Thread.java:856)
04-04 03:11:20.175: E/AndroidRuntime(4574): Caused by: java.lang.OutOfMemoryError
04-04 03:11:20.175: E/AndroidRuntime(4574):     at 

java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at java.lang.StringBuilder.append(StringBuilder.java:216)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at twitter4j.internal.org.json.JSONArray.join(JSONArray.java:363)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at twitter4j.internal.org.json.JSONArray.toString(JSONArray.java:605)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at twitter4j.internal.http.HttpResponse.asJSONArray(HttpResponse.java:192)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at twitter4j.internal.json.StatusJSONImpl.createStatusList(StatusJSONImpl.java:381)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at twitter4j.internal.json.z_T4JInternalJSONImplFactory.createStatusList(z_T4JInternalJSONImplFactory.java:74)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at twitter4j.TwitterImpl.getHomeTimeline(TwitterImpl.java:127)

它直接指向我的AsyncTask的doInBackground方法,其中調用getTwitterTimeLine()。

我怎么解決這個問題? 我希望能夠引入大量數據,並將其提取到多個列表視圖等。我讀了很多,我想也許我需要排隊任務,其中一個是占用大量內存,所以我研究和使用正確使用AsyncTask ,但這沒有任何影響,我仍然有內存不足的問題。

無論如何如何解決/繞過這個? 我讀了LoaderManager但是我想在最后一次調用時關閉它,因為它會導致一個很大的設計更改。

感謝您的任何幫助。

注意:getTwitterTimeLine方法調用調用api的twitter4j方法。

你不想在循環中像這樣觸發AsyncTask。 有一個固定的線程池大小,雖然兩個帳戶左右不足以最大化這個,但這是一個很好的編程習慣。 而是確定如何在單個異步任務中加載所有這些數據。 doInBackground()接受參數列表。 例如,您可以使用構造函數中設置的金額創建AsyncTask,並傳入帳戶以加載數據。

@Override
protected Map<Account, Data> doInBackground(Accounts...params){
    Map<Account, Data> resultMap = new HashMap<Account, Data>();
    for (Account account : params) {
        // do whatever!
    }
    return resultMap;
}

您不能依賴AsyncTasks進行並行執行

首次引入時,AsyncTasks在單個后台線程上串行執行。 從DONUT開始,這被改為一個線程池,允許多個任務並行運行。 從HONEYCOMB開始,任務在單個線程上執行,以避免由並行執行引起的常見應用程序錯誤。

至於twitter4j ......

at java.lang.StringBuilder.append(StringBuilder.java:216)
04-04 03:11:20.175: E/AndroidRuntime(4574):     at twitter4j.internal.org.json.JSONArray.join(JSONArray.java:363)

...它在內部使用StringBuilder。 在具有有限內存的設備上跨多個線程使用字符串連接必然會導致OOM。 如果要保存這些json字符串占用的內存,請使用JsonReader 至於並行執行,您可以使用ThreadPool支持的Threads並行執行它們。 在某些版本的android中,AsyncTasks是串行執行的。

事實證明,最終,這是因為Bitmaps沒有被內存管理。 盡管實現了android dev頁面描述的inSampleSize框架,有效地加載了你的位圖,但似乎維護和管理它們也是必要的。

感謝所有回復的人,提供了非常豐富的信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM