天天看點

應用記憶體優化之OnLowMemory&OnTrimMemory

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