前言
前段時間曾做過一個定制車載OS(基于Linux岩四、Android)的項目,該操作系統(tǒng)的內(nèi)存不足、內(nèi)存管理欠佳,并且在定制Linux內(nèi)核時給Payment曾撤、Music等應(yīng)用分配了較高的進程優(yōu)先級,導(dǎo)致其余應(yīng)用總是出現(xiàn)內(nèi)存被系統(tǒng)回收的情況晕粪,時常出現(xiàn)一些匪夷所思的BUG挤悉。
Android系統(tǒng)中的進程管理
進程優(yōu)先級的設(shè)置
對于每一個運行中的進程,Linux內(nèi)核都通過proc文件系統(tǒng)暴露這樣一個文件來允許其他程序修改指定進程的優(yōu)先級:/proc/[pid]/oom_score_adj
巫湘。(修改這個文件需要root權(quán)限)
這個文件允許的值的范圍是:-1000 ~ +1000之間装悲。值越小,表示進程越重要尚氛。
當(dāng)內(nèi)存非常緊張時诀诊,系統(tǒng)便會遍歷所有進程,以確定哪個進程需要被殺死以回收內(nèi)存阅嘶,此時便會讀取oom_score_adj 這個文件的值属瓣。
進程優(yōu)先級的影響范圍
在Android系統(tǒng)中,進程的優(yōu)先級影響著以下三個因素:
- 當(dāng)內(nèi)存緊張時讯柔,系統(tǒng)對于進程的回收策略
- 系統(tǒng)對于進程的CPU調(diào)度策略
- 虛擬機對于進程的內(nèi)存分配和垃圾回收策略
如何提高進程優(yōu)先級
- AndroidManifest.xml中的Application節(jié)點內(nèi)添加
android:persistent="true"
抡蛙; - 重載back按鍵事件,讓activity在后臺運行魂迄,不要Destroy粗截;
- 啟動Service,并設(shè)置前臺運行方式捣炬;
- 與NotificationManager交互熊昌,讓進程變成可感知進程;
- 發(fā)送/接收廣播湿酸,進行進程毙鲆伲活。
如何在Activity被銷毀時進行數(shù)據(jù)緩存
當(dāng)進程不可避免的被銷毀時推溃,可以考慮對頁面當(dāng)前數(shù)據(jù)昂利、部分控件狀態(tài)進行緩存,這樣可以避免部分bug美莫、優(yōu)化用戶體驗页眯。
Activity重建時梯捕,系統(tǒng)會在銷毀前調(diào)用onSaveInstanceState
方法(調(diào)用時序在onStop之前)厢呵,在重建時調(diào)用onRestoreInstanceState
方法恢復(fù)緩存數(shù)據(jù)。我們可以重寫onRestoreInstanceState
方法恢復(fù)數(shù)據(jù)傀顾,也可以在onCreate中使用savedInstanceState來恢復(fù)數(shù)據(jù)(需要對savedInstanceState判空)襟铭。
實例如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Log.d(TAG, "onCreate: ");
//恢復(fù)數(shù)據(jù)位置1(需要對savedInstanceState判空)
if (null != savedInstanceState) {
String string = savedInstanceState.getString("cache");
Log.d(TAG, "onCreate: " + string);
}
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//恢復(fù)數(shù)據(jù)位置2(官方推薦)
String string = savedInstanceState.getString("cache");
Log.d(TAG, "onRestoreInstanceState: " + string);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("cache", "Cicada");
}