2011-12-12 85 views
3

我想要實現:Android的內存管理中的onStop活動(或關閉屏幕)

  • 減少活動的內存使用情況是在屏幕上不再,即另一個活動已經開始
  • 此活動仍然處於導航堆棧中的能力,所以我假設我將不得不重新構建onStart內onStop中銷燬的內容,但不知道如何在所有視圖/按鈕均使用layout構建時如何執行此操作.xml的。

的情況:

我有一個Android應用程序,這是非常沉重的形象,但這些圖片是靜態的許多佈局的,具有相同的背景,按鈕圖像,導航等頭這導致我通過在layout.xml文件中指定所有的imageViews,它們的src屬性和位置,可以非常容易地構建佈局,而不會觸及代碼太多。而且這個工作很好,很容易起來和運行,但是現在有很多關於由於超過內存使用而關閉的報告。

在試圖清理於是就

,並允許GC刪除的圖像和看法不在屏幕上,我讀到一篇文章來(見問題的底部)的onDestroy方法中建議,抓住你的根保持元素在佈局中遞歸地遍歷樹去除視圖並將其解除綁定。但是,只有當後退按鈕被按下時,纔會觸發,並且根據文檔沒有保證。

因此,當我將新活動推入堆棧並且不想清理剛剛離開屏幕的內容時,onDestroy並不能幫助我。但使用onDestroy方法的優勢在於入口點從onCreate開始,所以視圖都是正確構建的。當我在onStop中使用這個方法時,當我開始一個新的活動時,內存get得到了很好的清理,但是因爲我已經使用layout.xml構建了所有的視圖,所以我不明白我需要什麼或者什麼如果我在onStop中銷燬所有內容,重新構建onStart,尤其是考慮到我從未在代碼中創建任何視圖,因爲它們都是由layout.xml文件設置的。

主要問題:當我開始一個新的活動時如何清理內存?如果上下文處理正確,gc是否會清理所有不在屏幕上的圖像並自動重新構建它?

這可以在onStop中以某種方式使用嗎?

@Override 
protected void onDestroy() { 
    super.onDestroy(); 

    unbindDrawables(findViewById(R.id.RootView)); 
    System.gc(); 
} 

private void unbindDrawables(View view) { 
    if (view.getBackground() != null) { 
     view.getBackground().setCallback(null); 
    } 
    if (view instanceof ViewGroup) { 
     for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
      unbindDrawables(((ViewGroup) view).getChildAt(i)); 
     } 
     ((ViewGroup) view).removeAllViews(); 
    } 
} 

回答

2

A) 使用的onCreate()/的onDestroy()將活動時在堆棧上得到時活性從堆棧中彈出分配,和unallocate。

B) 使用onStart()/ onStop()將在活動可見時進行分配,並在活動不可見時取消分配。

使用A)或B)。不要混合它們,否則你會經常分配或釋放資源。在你的情況下,我會將所有從onCreate()到onStart()以及從onDestroy()到onStop()的所有東西都移動。

另外,還可以考慮使用this.setContentView(null)或this。的setContentView(新圖())中的onStop(),以確保老的觀點可以被垃圾收集:

@Override 
    protected void onStop() { 
    super.onStop(); 
    View root = findViewById(R.id.RootView); 
    setContentView(new View(this)) 
    unbindDrawables(root); 
    System.gc(); 
    } 
1

我不認爲任何活動的回調都是做這個的理想場所。你的活動總是會變得非常緩慢。

我想你寧願堅持圖片,如果你可以,但你想放棄,如果系統需要資源。如果這(緩存)是你正在看的WeakReference是你的男人。看到這個將幫助你決定/理解的excellent article

此外,我不認爲android打算讓我們的開發人員擔心從佈局文件生成的視圖gc'd。只要你沒有強烈的意見,你應該沒問題。