Android代碼記憶體最佳化建議-OnTrimMemory最佳化

來源:互聯網
上載者:User

標籤:

原文  http://androidperformance.com/2015/07/20/Android代碼記憶體最佳化建議-OnTrimMemory最佳化/

OnTrimMemory 回調是 Android 4.0 之後提供的一個API,這個 API 是提供給開發人員的,它的主要作用是提示開發人員在系統記憶體不足的時候,通過處理部分資源來釋放記憶體,從而避免被 Android 系統殺死。這樣應用在下一次啟動的時候,速度就會比較快。

本文通過問答的方式,從各個方面來講解 OnTrimMemory 回調的使用過程和效果。想要開發高效能且使用者體驗良好的 Android 應用,那麼這篇文章你不應該錯過。

0. OnTrimMemory回調的作用?

OnTrimMemory是Android在4.0之後加入的一個回調,任何實現了ComponentCallbacks2介面的類都可以重寫實現這個回調方法.OnTrimMemory的主要作用就是 指導應用程式在不同的情況下進行自身的記憶體釋放,以避免被系統直接殺掉,提高應用程式的使用者體驗.

Android系統會根據不同等級的記憶體使用量情況,調用這個函數,並傳入對應的等級:

  • TRIM_MEMORY_UI_HIDDEN 表示應用程式的 所有UI介面 被隱藏了,即使用者點擊了Home鍵或者Back鍵導致應用的UI介面不可見.這時候應該釋放一些資源.

    TRIM_MEMORY_UI_HIDDEN這個等級比較常用,和下面六個的關係不是很強,所以單獨說.

下面三個等級是當我們的應用程式真正運行時的回調:

  • TRIM_MEMORY_RUNNING_MODERATE 表示應用程式正常運行,並且不會被殺掉。但是目前手機的記憶體已經有點低了,系統可能會開始根據LRU緩衝規則來去殺死進程了。
  • TRIM_MEMORY_RUNNING_LOW 表示應用程式正常運行,並且不會被殺掉。但是目前手機的記憶體已經非常低了,我們應該去釋放掉一些不必要的資源以提升系統的效能,同時這也會直接影響到我們應用程式的效能。
  • TRIM_MEMORY_RUNNING_CRITICAL 表示應用程式仍然正常運行,但是系統已經根據LRU緩衝規則殺掉了大部分緩衝的進程了。這個時候我們應當儘可能地去釋放任何不必要的資源,不然的話系統可能會繼續殺掉所有緩衝中的進程,並且開始殺掉一些本來應當保持啟動並執行進程,比如說後台啟動並執行服務。

當應用程式是緩衝的,則會收到以下幾種類型的回調:

  • TRIM_MEMORY_BACKGROUND 表示手機目前記憶體已經很低了,系統準備開始根據LRU緩衝來清理進程。這個時候我們的程式在LRU緩衝列表的最近位置,是不太可能被清理掉的,但這時去釋放掉一些比較容易恢複的資源能夠讓手機的記憶體變得比較充足,從而讓我們的程式更長時間地保留在緩衝當中,這樣當使用者返回我們的程式時會感覺非常順暢,而不是經曆了一次重新啟動的過程。
  • TRIM_MEMORY_MODERATE 表示手機目前記憶體已經很低了,並且我們的程式處於LRU緩衝列表的中間位置,如果手機記憶體還得不到進一步釋放的話,那麼我們的程式就有被系統殺掉的風險了。
  • TRIM_MEMORY_COMPLETE 表示手機目前記憶體已經很低了,並且我們的程式處於LRU緩衝列表的最邊緣位置,系統會最優先考慮殺掉我們的應用程式,在這個時候應當儘可能地把一切可以釋放的東西都進行釋放。
1. 哪些組件可以實現OnTrimMemory回調?
  • Application.onTrimMemory()
  • Activity.onTrimMemory()
  • Fragement.OnTrimMemory()
  • Service.onTrimMemory()
  • ContentProvider.OnTrimMemory()
2. OnTrimMemory回調中可以釋放哪些資源?

通常在架構階段就要考慮清楚,我們有哪些東西是要常駐記憶體的,有哪些是伴隨介面存在的.一般情況下,有下面幾種資源需要進行釋放:

  • 緩衝 緩衝包括一些檔案快取,圖片緩衝等,在使用者正常使用的時候這些緩衝很有作用,但當你的應用程式UI不可見的時候,這些緩衝就可以被清除以減少記憶體的使用.比如第三方圖片庫的緩衝.
  • 一些動態產生動態添加的View. 這些動態產生和添加的View且少數情況下才使用到的View,這時候可以被釋放,下次使用的時候再進行動態產生即可.比如原生案頭中,會在 OnTrimMemory的TRIM_MEMORY_MODERATE等級中,釋放所有AppsCustomizePagedView的資源,來保證在低記憶體的時候,案頭不會輕易被殺掉.
2.1 例子:釋放不常用到的View.

代碼出處:Launcher

Launcher.java:

?
1234567 @Overridepublic void onTrimMemory(int level) {    super.onTrimMemory(level);    if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {        mAppsCustomizeTabHost.onTrimMemory();    }}


AppsCustomizeTabHost.java:

?
123456 public void onTrimMemory() {    mContent.setVisibility(GONE);    // Clear the widget pages of all their subviews - this will trigger the widget previews    // to delete their bitmaps    mPagedView.clearAllWidgetPages();}


AppsCustomizePagedView.java:

?
1234567891011 public void clearAllWidgetPages() {    cancelAllTasks();    int count = getChildCount();    for (int i = 0; i < count; i++) {        View v = getPageAt(i);        if (v instanceof PagedViewGridLayout) {            ((PagedViewGridLayout) v).removeAllViewsOnPage();            mDirtyPageContent.set(i, true);        }    }}


PagedViewGridLayout.java

?
123456 @Overridepublic void removeAllViewsOnPage() {    removeAllViews();    mOnLayoutListener = null;    setLayerType(LAYER_TYPE_NONE, null);}

 

2.2 例子: 清除緩衝

代碼出處:Contact

?
12345678910111213 @Overridepublic void onTrimMemory(int level) {    if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {        // Clear the caches.  Note all pending requests will be removed too.        clear();    }} public void clear() {    mPendingRequests.clear();    mBitmapHolderCache.evictAll();    mBitmapCache.evictAll();}

 

3. OnTrimMemory和onStop的關係?

onTrimMemory()方法中的TRIM_MEMORY_UI_HIDDEN回調只有當我們程式中的所有UI組件全部不可見的時候才會觸發,這和onStop()方法還是有很大區別的,因為onStop()方法只是當一個Activity完全不可見的時候就會調用,比如說使用者開啟了我們程式中的另一個Activity。

因此,我們可以在onStop()方法中去釋放一些Activity相關的資源,比如說取消網路連接或者登出廣播接收器等,但是像UI相關的資源應該一直要等到onTrimMemory(TRIM_MEMORY_UI_HIDDEN)這個回調之後才去釋放,這樣可以保證如果使用者只是從我們程式的一個Activity回到了另外一個Activity,介面相關的資源都不需要重新載入,從而提升響應速度。

需要注意的是,onTrimMemory的TRIM_MEMORY_UI_HIDDEN 等級是在onStop方法之前調用的.

4. OnTrimMemory和OnLowMemory的關係?

在引入OnTrimMemory之前都是使用OnLowMemory回調,需要知道的是,OnLowMemory大概和 OnTrimMemory中的TRIM_MEMORY_COMPLETE層級相同,如果你想相容api<14的機器,那麼可以用 OnLowMemory來實現,否則你可以忽略OnLowMemory,直接使用OnTrimMemory即可.

5. 為什麼要調用OnTrimMemory?

儘管系統在記憶體不足的時候殺進程的順序是按照LRU Cache中從低到高來的,但是它同時也會考慮殺掉那些佔用記憶體較高的應用來讓系統更快地獲得更多的記憶體。

所以如果你的應用佔用記憶體較小,就可以增加不被殺掉的幾率,從而快速地恢複(如果不被殺掉,啟動的時候就是暖開機,否則就是冷啟動,其速度差在2~3倍)。

所以說在幾個不同的OnTrimMemory回調中釋放自己的UI資源,可以有效地提高使用者體驗。

6. 有哪些典型的使用情境?6.1 常駐記憶體的應用

一些常駐記憶體的應用,比如Launcher、資訊安全中心、電話等,在使用者使用過要退出的時候,需要調用OnTrimMemory來及時釋放使用者使用的時候所產生的多餘的記憶體資源:比如動態產生的View、圖片緩衝、Fragment等。

回到頂部6.2 有後台Service啟動並執行應用

這些應用不是常駐記憶體的,意味著可以被工作管理員殺掉,但是在某些情境下使用者不會去殺。這類應用程式套件括:音樂、下載等。使用者退出UI介面後,音樂還在繼續播放,下載程式還在運行。這時候音樂應該釋放部分UI資源和Cache。

Android代碼記憶體最佳化建議-OnTrimMemory最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.