理論上,一個具備良好行為的應用應該考慮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個),並且該進程優先級比較高,需要清理內存.
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