1.應用內存onLowMemory& onTrimMemory優化
onLowMemory& onTrimMemory簡介:
OnLowMemory是Android提供的API,在系統內存不足,所有后台程序(優先級為background的進程,不是指后台運行的進程)都被殺死時,系統會調用OnLowMemory。
OnTrimMemory是Android 4.0之后提供的API,系統會根據不同的內存狀態來回調。根據不同的內存狀態,來響應不同的內存釋放策略。
1.1 onLowMemory& onTrimMemory優化,需要釋放什么資源?
在內存緊張的時候,會回調OnLowMemory/OnTrimMemory,需要在回調方法中編寫釋放資源的代碼。
可以在資源緊張的時候,釋放UI 使用的資源資:Bitmap、數組、控件資源。
1.2 OnLowMemory
OnLowMemory是Android提供的API,在系統內存不足,所有后台程序(優先級為background的進程,不是指后台運行的進程)都被殺死時,系統會調用OnLowMemory。系統提供的回調有:
Application.onLowMemory()
Activity.OnLowMemory()
Fragement.OnLowMemory()
Service.OnLowMemory()
ContentProvider.OnLowMemory()
除了上述系統提供的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 ()在合適的時候注冊回調就可以了。通過這種自定義的方法,可以在很多地方注冊回調,而不需要局限於系統提供的組件。
onLowMemory 當后台程序已經終止資源還匱乏時會調用這個方法。好的應用程序一般會在這個方法里面釋放一些不必要的資源來應付當后台程序已經終止,前台應用程序內存還不夠時的情況。
1.3 OnTrimMemory
OnTrimMemory是Android 4.0之后提供的API,系統會根據不同的內存狀態來回調。系統提供的回調有:
Application.onTrimMemory()
Activity.onTrimMemory()
Fragement.OnTrimMemory()
Service.onTrimMemory()
ContentProvider.OnTrimMemory()
OnTrimMemory的參數是一個int數值,代表不同的內存狀態:
TRIM_MEMORY_COMPLETE:內存不足,並且該進程在后台進程列表最后一個,馬上就要被清理
TRIM_MEMORY_MODERATE:內存不足,並且該進程在后台進程列表的中部。
TRIM_MEMORY_BACKGROUND:內存不足,並且該進程是后台進程。
TRIM_MEMORY_UI_HIDDEN:內存不足,並且該進程的UI已經不可見了。
以上4個是4.0增加
TRIM_MEMORY_RUNNING_CRITICAL:內存不足(后台進程不足3個),並且該進程優先級比較高,需要清理內存
TRIM_MEMORY_RUNNING_LOW:內存不足(后台進程不足5個),並且該進程優先級比較高,需要清理內存
TRIM_MEMORY_RUNNING_MODERATE:內存不足(后台進程超過5個),並且該進程優先級比較高,需要清理內存
以上3個是4.1增加
系統也提供了一個ComponentCallbacks2,通過Context.registerComponentCallbacks()注冊后,就會被系統回調到。
1.4 OnLowMemory和OnTrimMemory的比較
1,OnLowMemory被回調時,已經沒有后台進程;而onTrimMemory被回調時,還有后台進程。
2,OnLowMemory是在最后一個后台進程被殺時調用,一般情況是low memory killer 殺進程后觸發;而OnTrimMemory的觸發更頻繁,每次計算進程優先級時,只要滿足條件,都會觸發。
3,通過一鍵清理后,OnLowMemory不會被觸發,而OnTrimMemory會被觸發一次。
使用舉例:
1 @Override 2 public void onTrimMemory(int level) { 3 Log.e(TAG, " onTrimMemory ... level:" + level); 6 } 7 8 @Override 9 public void onLowMemory() { 11 Log.e(TAG, " onLowMemory ... "); 13 }
2.系統回調優化
2.1 回調原理:
在Application、 Activity、Fragement、Service、ContentProvider中都可以重寫回調方法,對OnLowMemory/OnTrimMemory進行回調,在回調方法中實現資源釋放的實現。
以Activity為例,在Activity源碼中能夠看到對於onTrimMemory的定義,因此在回調的時候重寫方法即可。
public void onTrimMemory(int level) { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onTrimMemory " + this + ": " + level); mCalled = true; mFragments.dispatchTrimMemory(level); }
2.2 釋放資源:
在onTrimMemory釋放資源,釋放圖片、數組、緩存等資源。
@Override public void onTrimMemory(int level) { // TODO Auto-generated method stub DLog.d(" onTrimMemory ... level:" + level); switch(level) { case TRIM_MEMORY_UI_HIDDEN: //釋放資源 /*編寫釋放資源代碼*/ } break; } super.onTrimMemory(level); }
下面是釋放Bitmap的示例代碼片段:
// 先判斷是否已經回收 if(bitmap != null && !bitmap.isRecycled()){ // 回收並且置為null bitmap.recycle(); bitmap = null; } System.gc();
list占用方法:
list.clear();然后在置空。
3.實現ComponentCallbacks
OnLowMemory除了上述系統提供的API,還可以自己實現ComponentCallbacks,通過API注冊,這樣也能得到OnLowMemory回調。例如:
public static class ViewComponentCallbacks implements ComponentCallbacks { @Override public void onConfigurationChanged(Configuration arg) { } @Override public void onLowMemory() { //do release operation } }
注冊自定義的回調類:
ViewComponentCallbacks callBacks =new ViewComponentCallbacks(); this.registerComponentCallbacks( callBacks );
回調之后,即可進行重寫:
@Override public void onLowMemory() { // TODO Auto-generated method stub //釋放資源的方法 super.onLowMemory(); }