正確應對系統內存不足,OnLowMemory和OnTrimMemory回調


理論上,一個具備良好行為的應用應該考慮Android系統內存緊張的問題,這樣有助於維持一個良好的生態。在前人的基礎上,本文對OnLowMemory和OnTrimMemory回調進行了總結。

1. OnLowMemory

OnLowMemory是Android提供的API,在系統內存不足,所有后台程序(優先級為background的進程,不是指后台運行的進程)都被殺死時,系統會調用OnLowMemory。

系統為其提供回調的組件有:Application/Activity/Fragementice/Service/ContentProvider

除了上述系統提供的API,還可以自己實現ComponentCallbacks,通過API注冊,這樣也能得到OnLowMemory回調。例如:

public static class MyCallback implements ComponentCallbacks { 
        @Override
        public void onConfigurationChanged(Configuration arg) { 
        }
 
        @Override
        public void onLowMemory() {
            //do release operation
        }
    }

然后,通過

Context.registerComponentCallbacks()

在合適的時候注冊回調就可以了。通過這種自定義的方法,可以在很多地方注冊回調,而不需要局限於系統提供的組件。

2. OnTrimMemory

OnTrimMemory是Android 4.0之后提供的API,系統會根據不同的內存狀態來回調。系統提供的回調有:Application/Activity/Fragement/Service/ContentProvider

OnTrimMemory的參數是一個int數值,代表不同的內存狀態:

  • TRIM_MEMORY_COMPLETE:內存不足,並且該進程在后台進程列表最后一個,馬上就要被清理

  • TRIM_MEMORY_MODERATE:內存不足,並且該進程在后台進程列表的中部。

  • TRIM_MEMORY_BACKGROUND:內存不足,並且該進程是后台進程。

  • TRIM_MEMORY_UI_HIDDEN:內存不足,並且該進程的UI已經不可見了。

  • TRIM_MEMORY_RUNNING_CRITICAL:內存不足(后台進程不足3個),並且該進程優先級比較高,需要清理內存

  • TRIM_MEMORY_RUNNING_LOW:內存不足(后台進程不足5個),並且該進程優先級比較高,需要清理內存

  • TRIM_MEMORY_RUNNING_MODERATE:內存不足(后台進程超過5個),並且該進程優先級比較高,需要清理內存.

對於OnTrimMemory,系統也提供了一個ComponentCallbacks2,可以在非系統組件里收到回調,如下(其實ComponentCallbacks2繼承了ComponentCallbacks):
   public static class MyCallback implements ComponentCallbacks2 {

        @Override
        public void onTrimMemory(int level) {
            
        }

        @Override
        public void onConfigurationChanged(Configuration newConfig) {

        }

        @Override
        public void onLowMemory() {

        }
    }

通過

Context.registerComponentCallbacks()

注冊后,就會被系統回調到。

3. OnLowMemory和OnTrimMemory的比較

  • OnLowMemory被回調時,已經沒有后台進程;而onTrimMemory被回調時,還有后台進程。

  • OnLowMemory是在最后一個后台進程被殺時調用,一般情況是low memory killer 殺進程后觸發;而OnTrimMemory的觸發更頻繁,每次計算進程優先級時,只要滿足條件,都會觸發。

  • 通過一鍵清理后,OnLowMemory不會被觸發,而OnTrimMemory會被觸發一次。

4. 總結

也許大家不希望在每個系統組件里都重載OnLowMemory和OnTrimMemory方法,這樣確實很繁瑣,但是需要指出的是,在持有大量內存資源系統組件中重載這兩個方法是很有必要的,建議釋放掉非必要功能對於內存的占用。

舉例來說,播放視頻的activity在內存緊張時可以放棄彈幕功能,放棄聊天評論等功能。

又比如,在application注冊一個全局的OnTrimMemory回調監聽,內存緊張時停止一些非必要功能,如關閉推送進程,關閉后台service等

 


轉自:https://www.jianshu.com/p/a5712bdb2dfd


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM