Android代碼內(nèi)存優(yōu)化建議-Android官方篇

前言

為了使垃圾回收器可以正常釋放程序所占用的內(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末故痊,一起剝皮案震驚了整個(gè)濱河市顶瞳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌愕秫,老刑警劉巖慨菱,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異戴甩,居然都是意外死亡符喝,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門甜孤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)协饲,“玉大人,你說(shuō)我怎么就攤上這事缴川≤猿恚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵把夸,是天一觀的道長(zhǎng)而线。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么膀篮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任嘹狞,我火速辦了婚禮,結(jié)果婚禮上誓竿,老公的妹妹穿的比我還像新娘磅网。我一直安慰自己,他們只是感情好烤黍,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布知市。 她就那樣靜靜地躺著,像睡著了一般速蕊。 火紅的嫁衣襯著肌膚如雪嫂丙。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,842評(píng)論 1 290
  • 那天规哲,我揣著相機(jī)與錄音跟啤,去河邊找鬼。 笑死唉锌,一個(gè)胖子當(dāng)著我的面吹牛隅肥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播袄简,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼腥放,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了绿语?” 一聲冷哼從身側(cè)響起秃症,我...
    開(kāi)封第一講書(shū)人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吕粹,沒(méi)想到半個(gè)月后种柑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匹耕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年聚请,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稳其。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驶赏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欢际,到底是詐尸還是另有隱情母市,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布损趋,位于F島的核電站患久,受9級(jí)特大地震影響椅寺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蒋失,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一返帕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧篙挽,春花似錦荆萤、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至煮落,卻和暖如春敞峭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蝉仇。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工旋讹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人轿衔。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓沉迹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親害驹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鞭呕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容