Android 內存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會被觸發一次。

使用舉例:

 @Override
 public void onTrimMemory(int level) {
 Log.e(TAG, " onTrimMemory ... level:" + level); 
 }
 
 @Override
 public void onLowMemory() { 
 Log.e(TAG, " onLowMemory ... "); 
 }

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();
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章