2013-03-21 52 views
1

在MainActivity中,每x秒創建一個新的AsyncTask,我調用new RTask(this).execute(param);執行異步發送數據到服務器。我認爲創建一個新任務往往會導致內存泄漏。所以當垃圾收集器釋放內存,我怎樣才能將任務引用設置爲null以允許收集它? 我試過在onPostExecute()之內使用this.cancel(true);,但是我讀到過,由於Android框架的錯誤,onpost永遠不會被調用。任何建議將不勝感激。垃圾收集器如何釋放AsyncTask分配的內存

感謝

+0

你確定onPostExecute從來沒有被調用,我似乎使用它,並沒有失望過它,經常..但是回到關注的主要領域,GC,嘗試將其設置爲null並手動刪除所有對這個變量的引用,嘗試n隔離它..也是這this.cancel(真)另外應該是好 – 2013-03-21 11:00:54

+0

@stack_ved \t 感謝您的回答,我放心,所以當我實例化一個新的任務,一個(已完成他的任務)將自動從GC中收集,因爲他的引用將被設置爲null? – Ant4res 2013-03-21 11:25:29

回答

4

其實,不應該因爲除非你持有從param給它的任何參考或產生內部doInBackground()內存泄漏與AsyncTask回收任何問題。

所以,您可能會認爲,如果您正在創建許多長時間運行的AsyncTasks,那麼它會導致一些內存問題。其實這是不正確的(至少在最新的Android版本上)。 AsyncTasksource code表明

  • 它採用單界執行人:

    private static final int CORE_POOL_SIZE = 5; 
    private static final int MAXIMUM_POOL_SIZE = 128; 
    private static final int KEEP_ALIVE = 1; 
    
    public static final Executor THREAD_POOL_EXECUTOR 
        = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, 
          TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); 
    

    這意味着,執行將無法運行超過128個AsyncTasks同一時間(128不是按我的理解非常大)。

  • 它使用有限的查詢爲執行人:

    private static final BlockingQueue<Runnable> sPoolWorkQueue = 
         new LinkedBlockingQueue<Runnable>(10); 
    

因此,基於以上幾點,創建並運行,同時AsyncTasks數量是有限的,沒有這麼大。因此,如果AsyncTask內的代碼不會產生任何內存泄漏,那麼根據我的理解,這沒有問題。同一時間,Android不會讓你用AsyncTasks發送垃圾郵件。結帳ThreadPoolExecutors description以熟悉其管理內存的方式(如果您擔心同時創建的線程過多)。

特別是在你的情況下,我認爲在前一個請求尚未完成的情況下執行另一個請求到服務器是個好主意(在類似請求的情況下),也沒有必要執行許多頻繁的小事請求 - 在這種情況下,您的應用程序會耗盡電池電量。

關於cancel()呼叫,基於Android documentation for AsyncTask

取消任務

任務可以在任何時候通過調用取消(布爾)被取消。 調用此方法將導致後續調用isCancelled()至 返回true。在調用這個方法之後,onCostlled(Object)將會在 doInBackground(Object [])返回後調用onPostExecute(Object)的 。爲了確保任務是儘快取消 ,應始終從doInBackground檢查 isCancelled(返回值)定期(對象[]),如果可能的話 (例如一個循環中。)

所以,我不確定你的意思是「我嘗試過使用它。取消(真);內onPostExecute()」,而cancel()無關,如果從onPostExecute()調用,它可以從AsyncTaskdoInBackground()叫出來,這是一個很好的做法,呼籲isCancelled()如果你爲了有一個循環,AsyncTask停止其執行一次cancel()稱爲。

+0

如果我將MainActivity傳遞給AsyncTask構造函數以更改活動全局變量值,會出現問題嗎? – Ant4res 2013-03-21 12:30:11

+0

如果您將保持您的AsyncTask無限期運行,那麼我會懷疑存在問題。但是,如果您只是在進行網絡請求,那麼在超時/響應完成後,AsyncTask將結束=>不泄漏。 – sandrstar 2013-03-21 12:54:57

+0

謝謝!你的答案非常有用! – Ant4res 2013-03-21 13:26:45

1

如何分配的垃圾收集器釋放的AsyncTask內存

像它釋放內存用於其他任何類,有什麼特別的一個的AsyncTask,一旦任務完成後它會被垃圾收集,只要沒有其他班級提到它將任務引用設爲null將有所幫助。

+0

謝謝你的回答! – Ant4res 2013-03-21 13:27:25