前言
為了使垃圾回收器可以正常釋放程序所占用的內(nèi)存诉探,在編寫(xiě)代碼的時(shí)候就一定要注意盡量避免出現(xiàn)內(nèi)存泄漏的情況(通常都是由于全局成員變量持有對(duì)象引用所導(dǎo)致的)棍厌,并且在適當(dāng)?shù)臅r(shí)候去釋放對(duì)象引用。對(duì)于大多數(shù)的應(yīng)用程序而言阳液,后面其它的事情就可以都交給垃圾回收器去完成了帘皿,如果一個(gè)對(duì)象的引用不再被其它對(duì)象所持有畸陡,那么系統(tǒng)就會(huì)將這個(gè)對(duì)象所分配的內(nèi)存進(jìn)行回收丁恭。
我們?cè)陂_(kāi)發(fā)軟件的時(shí)候應(yīng)當(dāng)自始至終都把內(nèi)存的問(wèn)題充分考慮進(jìn)去,這樣的話才能開(kāi)發(fā)出更加高性能的軟件墓陈。而內(nèi)存問(wèn)題也并不是無(wú)規(guī)律可行的第献,Android系統(tǒng)給我們提出了很多內(nèi)存優(yōu)化的建議技巧庸毫,只要按照這些技巧來(lái)編寫(xiě)程序,就可以讓我們的程序在內(nèi)存性能發(fā)面表現(xiàn)得相當(dāng)不錯(cuò)利花。
正文
本文原文來(lái)自Android開(kāi)發(fā)者官網(wǎng)Managing Your App's Memory章節(jié)中的
How Your App Should Manage Memory部分炒事。是Android官方幫助應(yīng)用開(kāi)發(fā)者更好地管理應(yīng)用的內(nèi)存而寫(xiě)的蔫慧。作為一個(gè)應(yīng)用程序開(kāi)發(fā)者,你需要在你開(kāi)發(fā)應(yīng)用程序的時(shí)時(shí)刻刻都考慮內(nèi)存問(wèn)題崭闲。
1. 節(jié)制地使用Service
如果應(yīng)用程序當(dāng)中需要使用Service來(lái)執(zhí)行后臺(tái)任務(wù)的話威蕉,請(qǐng)一定要注意只有當(dāng)任務(wù)正在執(zhí)行的時(shí)候才應(yīng)該讓Service運(yùn)行起來(lái)韧涨。另外,當(dāng)任務(wù)執(zhí)行完之后去停止Service的時(shí)候如孝,要小心Service停止失敗導(dǎo)致內(nèi)存泄漏的情況娩贷。
當(dāng)我們啟動(dòng)一個(gè)Service時(shí)彬祖,系統(tǒng)會(huì)傾向于將這個(gè)Service所依賴的進(jìn)程進(jìn)行保留,這樣就會(huì)導(dǎo)致這個(gè)進(jìn)程變得非常消耗內(nèi)存甜熔。并且腔稀,系統(tǒng)可以在LRU cache當(dāng)中緩存的進(jìn)程數(shù)量也會(huì)減少羽历,導(dǎo)致切換應(yīng)用程序的時(shí)候耗費(fèi)更多性能窄陡。嚴(yán)重的話,甚至有可能會(huì)導(dǎo)致崩潰,因?yàn)橄到y(tǒng)在內(nèi)存非常吃緊的時(shí)候可能已無(wú)法維護(hù)所有正在運(yùn)行的Service所依賴的進(jìn)程了币叹。
為了能夠控制Service的生命周期模狭,Android官方推薦的最佳解決方案就是使用IntentService,這種Service的最大特點(diǎn)就是當(dāng)后臺(tái)任務(wù)執(zhí)行結(jié)束后會(huì)自動(dòng)停止驱富,從而極大程度上避免了Service內(nèi)存泄漏的可能性匹舞。
讓一個(gè)Service在后臺(tái)一直保持運(yùn)行赐稽,即使它并不執(zhí)行任何工作,這是編寫(xiě)Android程序時(shí)最糟糕的做法之一晰绎。所以Android官方極度建議開(kāi)發(fā)人員們不要過(guò)于貪婪荞下,讓Service在后臺(tái)一直運(yùn)行史飞,這不僅可能會(huì)導(dǎo)致手機(jī)和程序的性能非常低下祸憋,而且被用戶發(fā)現(xiàn)了之后也有可能直接導(dǎo)致我們的軟件被卸載
2. 當(dāng)界面不可見(jiàn)時(shí)釋放內(nèi)存
當(dāng)用戶打開(kāi)了另外一個(gè)程序,我們的程序界面已經(jīng)不再可見(jiàn)的時(shí)候掸鹅,我們應(yīng)當(dāng)將所有和界面相關(guān)的資源進(jìn)行釋放巍沙。在這種場(chǎng)景下釋放資源可以讓系統(tǒng)緩存后臺(tái)進(jìn)程的能力顯著增加荷鼠,因此也會(huì)讓用戶體驗(yàn)變得更好允乐。
那么我們?nèi)绾尾拍苤莱绦蚪缑媸遣皇且呀?jīng)不可見(jiàn)了呢?其實(shí)很簡(jiǎn)單蠢笋,只需要在Activity中重寫(xiě)onTrimMemory()方法昨寞,然后在這個(gè)方法中監(jiān)聽(tīng)TRIM_MEMORY_UI_HIDDEN這個(gè)級(jí)別,一旦觸發(fā)了之后就說(shuō)明用戶已經(jīng)離開(kāi)了我們的程序歼狼,那么此時(shí)就可以進(jìn)行資源釋放操作了享怀,如下所示:
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
switch (level) {
case TRIM_MEMORY_UI_HIDDEN:
// 進(jìn)行資源釋放操作
break;
}
}
注意onTrimMemory()方法中的TRIM_MEMORY_UI_HIDDEN回調(diào)只有當(dāng)我們程序中的所有UI組件全部不可見(jiàn)的時(shí)候才會(huì)觸發(fā)凹蜈,這和onStop()方法還是有很大區(qū)別的仰坦,因?yàn)閛nStop()方法只是當(dāng)一個(gè)Activity完全不可見(jiàn)的時(shí)候就會(huì)調(diào)用,比如說(shuō)用戶打開(kāi)了我們程序中的另一個(gè)Activity玫霎。因此庶近,我們可以在onStop()方法中去釋放一些Activity相關(guān)的資源眷蚓,比如說(shuō)取消網(wǎng)絡(luò)連接或者注銷廣播接收器等沙热,但是像UI相關(guān)的資源應(yīng)該一直要等到onTrimMemory(TRIM_MEMORY_UI_HIDDEN)這個(gè)回調(diào)之后才去釋放,這樣可以保證如果用戶只是從我們程序的一個(gè)Activity回到了另外一個(gè)Activity投队,界面相關(guān)的資源都不需要重新加載敷鸦,從而提升響應(yīng)速度扒披。
3.當(dāng)內(nèi)存緊張時(shí)釋放內(nèi)存
除了剛才講的TRIM_MEMORY_UI_HIDDEN這個(gè)回調(diào)圃泡,onTrimMemory()方法還有很多種其它類型的回調(diào)洞焙,可以在手機(jī)內(nèi)存降低的時(shí)候及時(shí)通知我們。我們應(yīng)該根據(jù)回調(diào)中傳入的級(jí)別來(lái)去決定如何釋放應(yīng)用程序的資源:
3.1 應(yīng)用程序正在運(yùn)行時(shí)
TRIM_MEMORY_RUNNING_MODERATE 表示應(yīng)用程序正常運(yùn)行熔任,并且不會(huì)被殺掉疑苔。但是目前手機(jī)的內(nèi)存已經(jīng)有點(diǎn)低了甸鸟,系統(tǒng)可能會(huì)開(kāi)始根據(jù)LRU緩存規(guī)則來(lái)去殺死進(jìn)程了抢韭。
TRIM_MEMORY_RUNNING_LOW 表示應(yīng)用程序正常運(yùn)行刻恭,并且不會(huì)被殺掉。但是目前手機(jī)的內(nèi)存已經(jīng)非常低了鞍匾,我們應(yīng)該去釋放掉一些不必要的資源以提升系統(tǒng)的性能橡淑,同時(shí)這也會(huì)直接影響到我們應(yīng)用程序的性能咆爽。
TRIM_MEMORY_RUNNING_CRITICAL 表示應(yīng)用程序仍然正常運(yùn)行伍掀,但是系統(tǒng)已經(jīng)根據(jù)LRU緩存規(guī)則殺掉了大部分緩存的進(jìn)程了。這個(gè)時(shí)候我們應(yīng)當(dāng)盡可能地去釋放任何不必要的資源濒蒋,不然的話系統(tǒng)可能會(huì)繼續(xù)殺掉所有緩存中的進(jìn)程沪伙,并且開(kāi)始?xì)⒌粢恍┍緛?lái)應(yīng)當(dāng)保持運(yùn)行的進(jìn)程围橡,比如說(shuō)后臺(tái)運(yùn)行的服務(wù)缕贡。
3.2 應(yīng)用程序被緩存
TRIM_MEMORY_BACKGROUND 表示手機(jī)目前內(nèi)存已經(jīng)很低了,系統(tǒng)準(zhǔn)備開(kāi)始根據(jù)LRU緩存來(lái)清理進(jìn)程贮配。這個(gè)時(shí)候我們的程序在LRU緩存列表的最近位置塞赂,是不太可能被清理掉的宴猾,但這時(shí)去釋放掉一些比較容易恢復(fù)的資源能夠讓手機(jī)的內(nèi)存變得比較充足,從而讓我們的程序更長(zhǎng)時(shí)間地保留在緩存當(dāng)中沦辙,這樣當(dāng)用戶返回我們的程序時(shí)會(huì)感覺(jué)非常順暢怕轿,而不是經(jīng)歷了一次重新啟動(dòng)的過(guò)程辟拷。
TRIM_MEMORY_MODERATE 表示手機(jī)目前內(nèi)存已經(jīng)很低了衫冻,并且我們的程序處于LRU緩存列表的中間位置隅俘,如果手機(jī)內(nèi)存還得不到進(jìn)一步釋放的話,那么我們的程序就有被系統(tǒng)殺掉的風(fēng)險(xiǎn)了碌宴。
TRIM_MEMORY_COMPLETE 表示手機(jī)目前內(nèi)存已經(jīng)很低了蒙畴,并且我們的程序處于LRU緩存列表的最邊緣位置贰镣,系統(tǒng)會(huì)最優(yōu)先考慮殺掉我們的應(yīng)用程序,在這個(gè)時(shí)候應(yīng)當(dāng)盡可能地把一切可以釋放的東西都進(jìn)行釋放膳凝。
因?yàn)閛nTrimMemory()是在API14才加進(jìn)來(lái)的碑隆,所以如果要支持API14之前的話,則可以考慮 onLowMemory()這個(gè)方法上煤,它粗略的相等于onTrimMemory()回調(diào)的TRIM_MEMORY_COMPLETE事件。
注意:當(dāng)系統(tǒng)安裝LRU cache殺進(jìn)程的時(shí)候著淆,盡管大部分時(shí)間是從下往上按順序殺劫狠,有時(shí)候系統(tǒng)也會(huì)將占用內(nèi)存比較大的進(jìn)程納入被殺范圍,以盡快得到足夠的內(nèi)存嘉熊。所以你的應(yīng)用在LRU list中占用的內(nèi)存越少遥赚,你就越能避免被殺掉,當(dāng)你恢復(fù)的時(shí)候也會(huì)更快阐肤。
4. 檢查你應(yīng)該使用多少的內(nèi)存
正如前面提到的,每一個(gè)Android設(shè)備都會(huì)有不同的RAM總大小與可用空間讲坎,因此不同設(shè)備為app提供了不同大小的heap限制孕惜。你可以通過(guò)調(diào)用getMemoryClass()來(lái)獲取你的app的可用heap大小。如果你的app嘗試申請(qǐng)更多的內(nèi)存晨炕,會(huì)出現(xiàn)OutOfMemory的錯(cuò)誤衫画。
在一些特殊的情景下,你可以通過(guò)在manifest的application標(biāo)簽下添加largeHeap=true的屬性來(lái)聲明一個(gè)更大的heap空間瓮栗。如果你這樣做削罩,你可以通過(guò)getLargeMemoryClass()來(lái)獲取到一個(gè)更大的heap size。
然而费奸,能夠獲取更大heap的設(shè)計(jì)本意是為了一小部分會(huì)消耗大量RAM的應(yīng)用(例如一個(gè)大圖片的編輯應(yīng)用)弥激。不要輕易的因?yàn)槟阈枰褂么罅康膬?nèi)存而去請(qǐng)求一個(gè)大的heap size。只有當(dāng)你清楚的知道哪里會(huì)使用大量的內(nèi)存并且為什么這些內(nèi)存必須被保留時(shí)才去使用large heap. 因此請(qǐng)盡量少使用large heap愿阐。使用額外的內(nèi)存會(huì)影響系統(tǒng)整體的用戶體驗(yàn)微服,并且會(huì)使得GC的每次運(yùn)行時(shí)間更長(zhǎng)。在任務(wù)切換時(shí)缨历,系統(tǒng)的性能會(huì)變得大打折扣以蕴。
另外, large heap并不一定能夠獲取到更大的heap。在某些有嚴(yán)格限制的機(jī)器上辛孵,large heap的大小和通常的heap size是一樣的丛肮。因此即使你申請(qǐng)了large heap,你還是應(yīng)該通過(guò)執(zhí)行g(shù)etMemoryClass()來(lái)檢查實(shí)際獲取到的heap大小魄缚。
5. 避免在Bitmap上浪費(fèi)內(nèi)存
當(dāng)我們讀取一個(gè)Bitmap圖片的時(shí)候宝与,有一點(diǎn)一定要注意,就是千萬(wàn)不要去加載不需要的分辨率鲜滩。在一個(gè)很小的ImageView上顯示一張高分辨率的圖片不會(huì)帶來(lái)任何視覺(jué)上的好處伴鳖,但卻會(huì)占用我們相當(dāng)多寶貴的內(nèi)存。需要僅記的一點(diǎn)是徙硅,將一張圖片解析成一個(gè)Bitmap對(duì)象時(shí)所占用的內(nèi)存并不是這個(gè)圖片在硬盤中的大小榜聂,可能一張圖片只有100k你覺(jué)得它并不大,但是讀取到內(nèi)存當(dāng)中是按照像素點(diǎn)來(lái)算的嗓蘑,比如這張圖片是15001000像素须肆,使用的ARGB_8888顏色類型匿乃,那么每個(gè)像素點(diǎn)就會(huì)占用4個(gè)字節(jié),總內(nèi)存就是15001000*4字節(jié)豌汇,也就是5.7M幢炸,這個(gè)數(shù)據(jù)看起來(lái)就比較恐怖了。
6. 使用優(yōu)化過(guò)的數(shù)據(jù)集合
利用Android Framework里面優(yōu)化過(guò)的容器類拒贱,例如SparseArray, SparseBooleanArray, 與 LongSparseArray宛徊。 通常的HashMap的實(shí)現(xiàn)方式更加消耗內(nèi)存,因?yàn)樗枰粋€(gè)額外的實(shí)例對(duì)象來(lái)記錄Mapping操作逻澳。另外闸天,SparseArray更加高效在于他們避免了對(duì)key與value的autobox自動(dòng)裝箱,并且避免了裝箱后的解箱斜做。
7. 知曉內(nèi)存的開(kāi)支情況
我們還應(yīng)當(dāng)清楚我們所使用語(yǔ)言的內(nèi)存開(kāi)支和消耗情況苞氮,并且在整個(gè)軟件的設(shè)計(jì)和開(kāi)發(fā)當(dāng)中都應(yīng)該將這些信息考慮在內(nèi)∪勘疲可能有一些看起來(lái)無(wú)關(guān)痛癢的寫(xiě)法笼吟,結(jié)果卻會(huì)導(dǎo)致很大一部分的內(nèi)存開(kāi)支,例如:
- 使用枚舉通常會(huì)比使用靜態(tài)常量要消耗兩倍以上的內(nèi)存霸旗,在Android開(kāi)發(fā)當(dāng)中我們應(yīng)當(dāng)盡可能地不使用枚舉贷帮。
- 任何一個(gè)Java類,包括內(nèi)部類定硝、匿名類皿桑,都要占用大概500字節(jié)的內(nèi)存空間。
- 任何一個(gè)類的實(shí)例要消耗12-16字節(jié)的內(nèi)存開(kāi)支蔬啡,因此頻繁創(chuàng)建實(shí)例也是會(huì)一定程序上影響內(nèi)存的诲侮。
- 在使用HashMap時(shí),即使你只設(shè)置了一個(gè)基本數(shù)據(jù)類型的鍵箱蟆,比如說(shuō)int沟绪,但是也會(huì)按照對(duì)象的大小來(lái)分配內(nèi)存,大概是32字節(jié)空猜,而不是4字節(jié)绽慈。因此最好的辦法就是像上面所說(shuō)的一樣,使用優(yōu)化過(guò)的數(shù)據(jù)集合辈毯。
8. 謹(jǐn)慎使用抽象編程
許多程序員都喜歡各種使用抽象來(lái)編程坝疼,認(rèn)為這是一種很好的編程習(xí)慣。當(dāng)然谆沃,這一點(diǎn)不可否認(rèn)钝凶,因?yàn)榈某橄蟮木幊谭椒ǜ用嫦驅(qū)ο螅以诖a的維護(hù)和可擴(kuò)展性方面都會(huì)有所提高唁影。但是耕陷,在Android上使用抽象會(huì)帶來(lái)額外的內(nèi)存開(kāi)支掂名,因?yàn)槌橄蟮木幊谭椒ㄐ枰帉?xiě)額外的代碼,雖然這些代碼根本執(zhí)行不到哟沫,但是卻也要映射到內(nèi)存當(dāng)中饺蔑,不僅占用了更多的內(nèi)存,在執(zhí)行效率方面也會(huì)有所降低嗜诀。當(dāng)然這里我并不是提倡大家完全不使用抽象編程猾警,而是謹(jǐn)慎使用抽象編程,不要認(rèn)為這是一種很酷的編程方式而去肆意使用它裹虫,只在你認(rèn)為有必要的情況下才去使用肿嘲。
9. 為序列化的數(shù)據(jù)使用nano protobufs
Protocol buffers是由Google為序列化結(jié)構(gòu)數(shù)據(jù)而設(shè)計(jì)的,一種語(yǔ)言無(wú)關(guān)筑公,平臺(tái)無(wú)關(guān),具有良好擴(kuò)展性的協(xié)議尊浪。類似XML匣屡,卻比XML更加輕量,快速拇涤,簡(jiǎn)單捣作。如果你需要為你的數(shù)據(jù)實(shí)現(xiàn)協(xié)議化,你應(yīng)該在客戶端的代碼中總是使用nano protobufs鹅士。通常的協(xié)議化操作會(huì)生成大量繁瑣的代碼券躁,這容易給你的app帶來(lái)許多問(wèn)題:增加RAM的使用量,顯著增加APK的大小掉盅,更慢的執(zhí)行速度也拜,更容易達(dá)到DEX的字符限制。
關(guān)于更多細(xì)節(jié)趾痘,請(qǐng)參考protobuf readme的"Nano version"章節(jié)慢哈。
10. 盡量避免使用依賴注入框架
現(xiàn)在有很多人都喜歡在Android工程當(dāng)中使用依賴注入框架,比如說(shuō)像Guice或者RoboGuice等永票,因?yàn)樗鼈兛梢院?jiǎn)化一些復(fù)雜的編碼操作卵贱,比如可以將下面的一段代碼:
class AndroidWay extends Activity {
TextView name;
ImageView thumbnail;
LocationManager loc;
Drawable icon;
String myName;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name = (TextView) findViewById(R.id.name);
thumbnail = (ImageView) findViewById(R.id.thumbnail);
loc = (LocationManager) getSystemService(Activity.LOCATION_SERVICE);
icon = getResources().getDrawable(R.drawable.icon);
myName = getString(R.string.app_name);
name.setText( "Hello, " + myName );
}
}
簡(jiǎn)化成這樣的一種寫(xiě)法:
@ContentView(R.layout.main)
class RoboWay extends RoboActivity {
@InjectView(R.id.name) TextView name;
@InjectView(R.id.thumbnail) ImageView thumbnail;
@InjectResource(R.drawable.icon) Drawable icon;
@InjectResource(R.string.app_name) String myName;
@Inject LocationManager loc;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
name.setText( "Hello, " + myName );
}
}
看上去確實(shí)十分誘人,我們甚至可以將findViewById()這一類的繁瑣操作全部省去了侣集。但是這些框架為了要搜尋代碼中的注解键俱,通常都需要經(jīng)歷較長(zhǎng)的初始化過(guò)程,并且還可能將一些你用不到的對(duì)象也一并加載到內(nèi)存當(dāng)中世分。這些用不到的對(duì)象會(huì)一直占用著內(nèi)存空間编振,可能要過(guò)很久之后才會(huì)得到釋放,相較之下罚攀,也許多敲幾行看似繁瑣的代碼才是更好的選擇党觅。
11. 謹(jǐn)慎使用external libraries
很多External library的代碼都不是為移動(dòng)網(wǎng)絡(luò)環(huán)境而編寫(xiě)的雌澄,在移動(dòng)客戶端則顯示的效率不高。至少杯瞻,當(dāng)你決定使用一個(gè)external library的時(shí)候镐牺,你應(yīng)該針對(duì)移動(dòng)網(wǎng)絡(luò)做繁瑣的porting與maintenance的工作。
即使是針對(duì)Android而設(shè)計(jì)的library魁莉,也可能是很危險(xiǎn)的睬涧,因?yàn)槊恳粋€(gè)library所做的事情都是不一樣的。例如旗唁,其中一個(gè)lib使用的是nano protobufs, 而另外一個(gè)使用的是micro protobufs畦浓。那么這樣,在你的app里面就有2種protobuf的實(shí)現(xiàn)方式检疫。這樣的沖突同樣可能發(fā)生在輸出日志讶请,加載圖片,緩存等等模塊里面屎媳。
同樣不要陷入為了1個(gè)或者2個(gè)功能而導(dǎo)入整個(gè)library的陷阱夺溢。如果沒(méi)有一個(gè)合適的庫(kù)與你的需求相吻合,你應(yīng)該考慮自己去實(shí)現(xiàn)烛谊,而不是導(dǎo)入一個(gè)大而全的解決方案风响。
12. 優(yōu)化整體性能
官方有列出許多優(yōu)化整個(gè)app性能的文章:Best Practices for Performance. 這篇文章就是其中之一。有些文章是講解如何優(yōu)化app的CPU使用效率丹禀,有些是如何優(yōu)化app的內(nèi)存使用效率状勤。
你還應(yīng)該閱讀optimizing your UI來(lái)為layout進(jìn)行優(yōu)化。同樣還應(yīng)該關(guān)注lint工具所提出的建議双泪,進(jìn)行優(yōu)化持搜。
13. 使用ProGuard來(lái)剔除不需要的代碼
ProGuard能夠通過(guò)移除不需要的代碼,重命名類攒读,域與方法等方對(duì)代碼進(jìn)行壓縮朵诫,優(yōu)化與混淆。使用ProGuard可以是的你的代碼更加緊湊薄扁,這樣能夠使用更少mapped代碼所需要的RAM剪返。
14. 對(duì)最終的APK使用zipalign
在編寫(xiě)完所有代碼,并通過(guò)編譯系統(tǒng)生成APK之后邓梅,你需要使用zipalign對(duì)APK進(jìn)行重新校準(zhǔn)脱盲。如果你不做這個(gè)步驟,會(huì)導(dǎo)致你的APK需要更多的RAM日缨,因?yàn)橐恍╊愃茍D片資源的東西不能被mapped钱反。
Notes::Google Play不接受沒(méi)有經(jīng)過(guò)zipalign的APK。
15. 分析你的RAM使用情況
一旦你獲取到一個(gè)相對(duì)穩(wěn)定的版本后,需要分析你的app整個(gè)生命周期內(nèi)使用的內(nèi)存情況面哥,并進(jìn)行優(yōu)化哎壳,更多細(xì)節(jié)請(qǐng)參考Investigating Your RAM Usage.
16. 使用多進(jìn)程
如果合適的話,有一個(gè)更高級(jí)的技術(shù)可以幫助你的app管理內(nèi)存使用:通過(guò)把你的app組件切分成多個(gè)組件尚卫,運(yùn)行在不同的進(jìn)程中归榕。這個(gè)技術(shù)必須謹(jǐn)慎使用,大多數(shù)app都不應(yīng)該運(yùn)行在多個(gè)進(jìn)程中吱涉。因?yàn)槿绻褂貌划?dāng)刹泄,它會(huì)顯著增加內(nèi)存的使用,而不是減少怎爵。當(dāng)你的app需要在后臺(tái)運(yùn)行與前臺(tái)一樣的大量的任務(wù)的時(shí)候特石,可以考慮使用這個(gè)技術(shù)歧沪。
一個(gè)典型的例子是創(chuàng)建一個(gè)可以長(zhǎng)時(shí)間后臺(tái)播放的Music Player鳄橘。如果整個(gè)app運(yùn)行在一個(gè)進(jìn)程中曲伊,當(dāng)后臺(tái)播放的時(shí)候赴穗,前臺(tái)的那些UI資源也沒(méi)有辦法得到釋放。類似這樣的app可以切分成2個(gè)進(jìn)程:一個(gè)用來(lái)操作UI逐沙,另外一個(gè)用來(lái)后臺(tái)的Service.
你可以通過(guò)在manifest文件中聲明'android:process'屬性來(lái)實(shí)現(xiàn)某個(gè)組件運(yùn)行在另外一個(gè)進(jìn)程的操作偏序。
<service android:name=".PlaybackService"
android:process=":background" />
更多關(guān)于使用這個(gè)技術(shù)的細(xì)節(jié)哼御,請(qǐng)參考原文题山,鏈接如下。
http://developer.android.com/training/articles/memory.html