久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Android Training - 管理應(yīng)用的內(nèi)存

 Joselyn_cui 2015-05-18

Random Access Memory(RAM)在任何軟件開發(fā)環(huán)境中都是一個(gè)很寶貴的資源,。這一點(diǎn)在物理內(nèi)存通常很有限的移動(dòng)操作系統(tǒng)上,,顯得尤為突出。盡管Android的Dalvik虛擬機(jī)扮演了常規(guī)的垃圾回收的角色,,但這并不意味著你可以忽視app的內(nèi)存分配與釋放的時(shí)機(jī)與地點(diǎn),。

為了GC能夠從你的app中及時(shí)回收內(nèi)存,你需要避免Memory Leaks(這通常由引用的不能釋放而導(dǎo)致)并且在適當(dāng)?shù)臅r(shí)機(jī)(下面會(huì)講到的lifecycle callbacks)來釋放引用,。對(duì)于大多數(shù)apps來說,,Dalvik的GC會(huì)自動(dòng)把離開活動(dòng)線程的對(duì)象進(jìn)行回收。

這篇文章會(huì)解釋Android如何管理app的進(jìn)程與內(nèi)存分配,,并且你可以在開發(fā)Android應(yīng)用的時(shí)候主動(dòng)的減少內(nèi)存的使用,。關(guān)于Java的資源管理機(jī)制,請(qǐng)參加其它書籍或者線上材料,。如果你正在尋找如何分析你的內(nèi)存使用情況的文章,,請(qǐng)參考這里Investigating Your RAM Usage

第1部分:Android是如何管理內(nèi)存的

Android并沒有提供內(nèi)存的交換區(qū)(Swap space),,但是它有使用pagingmemory-mapping(mmapping)的機(jī)制來管理內(nèi)存,。這意味著任何你修改的內(nèi)存(無論是通過分配新的對(duì)象還是訪問到mmaped pages的內(nèi)容)都會(huì)貯存在RAM中,,而且不能被paged out。因此唯一完整釋放內(nèi)存的方法是釋放那些你可能hold住的對(duì)象的引用,,這樣使得它能夠被GC回收,。只有一種例外是:如果系統(tǒng)想要在其他地方進(jìn)行reuse。

1)共享內(nèi)存

Android通過下面幾個(gè)方式在不同的Process中來共享RAM:

  • 每一個(gè)app的process都是從同一個(gè)被叫做Zygote的進(jìn)程中fork出來的,。Zygote進(jìn)程在系統(tǒng)啟動(dòng)并且載入通用的framework的代碼與資源之后開始啟動(dòng),。為了啟動(dòng)一個(gè)新的程序進(jìn)程,系統(tǒng)會(huì)fork Zygote進(jìn)程生成一個(gè)新的process,,然后在新的process中加載并運(yùn)行app的代碼,。這使得大多數(shù)的RAM pages被用來分配給framework的代碼與資源,并在應(yīng)用的所有進(jìn)程中進(jìn)行共享,。
  • 大多數(shù)static的數(shù)據(jù)被mmapped到一個(gè)進(jìn)程中,。這不僅僅使得同樣的數(shù)據(jù)能夠在進(jìn)程間進(jìn)行共享,而且使得它能夠在需要的時(shí)候被paged out,。例如下面幾種static的數(shù)據(jù):
    • Dalvik code (by placing it in a pre-linked .odex file for direct mmapping
    • App resources (by designing the resource table to be a structure that can be mmapped and by aligning the zip entries of the APK)
    • Traditional project elements like native code in .so files.
  • 在許多地方,,Android通過顯式的分配共享內(nèi)存區(qū)域(例如ashmem或者gralloc)來實(shí)現(xiàn)一些動(dòng)態(tài)RAM區(qū)域的能夠在不同進(jìn)程間的共享。例如,,window surfaces在app與screen compositor之間使用共享的內(nèi)存,,cursor buffers在content provider與client之間使用共享的內(nèi)存。

關(guān)于如何查看app所使用的共享內(nèi)存,,請(qǐng)查看Investigating Your RAM Usage

2)分配與回收內(nèi)存

這里有下面幾點(diǎn)關(guān)于Android如何分配與回收內(nèi)存的事實(shí):

  • 每一個(gè)進(jìn)程的Dalvik heap都有一個(gè)限制的虛擬內(nèi)存范圍,。這就是邏輯上講的heap size,它可以隨著需要進(jìn)行增長,,但是會(huì)有一個(gè)系統(tǒng)為它所定義的上限,。
  • 邏輯上講的heap size和實(shí)際物理上使用的內(nèi)存數(shù)量是不等的,Android會(huì)計(jì)算一個(gè)叫做Proportional Set Size(PSS)的值,,它記錄了那些和其他進(jìn)程進(jìn)行共享的內(nèi)存大小。(假設(shè)共享內(nèi)存大小是10M,,一共有20個(gè)Process在共享使用,,根據(jù)權(quán)重,可能認(rèn)為其中有0.3M才能真正算是你的進(jìn)程所使用的)
  • Dalvik heap與邏輯上的heap size不吻合,,這意味著Android并不會(huì)去做heap中的碎片整理用來關(guān)閉空閑區(qū)域,。Android僅僅會(huì)在heap的尾端出現(xiàn)不使用的空間時(shí)才會(huì)做收縮邏輯heap size大小的動(dòng)作。但是這并不是意味著被heap所使用的物理內(nèi)存大小不能被收縮,。在垃圾回收之后,,Dalvik會(huì)遍歷heap并找出不使用的pages,然后使用madvise把那些pages返回給kernal,。因此,,成對(duì)的allocations與deallocations大塊的數(shù)據(jù)可以使得物理內(nèi)存能夠被正常的回收,。然而,回收碎片化的內(nèi)存則會(huì)使得效率低下很多,,因?yàn)槟切┧槠姆峙漤撁嬉苍S會(huì)被其他地方所共享到,。

3)限制應(yīng)用的內(nèi)存

為了維持多任務(wù)的功能環(huán)境,Android為每一個(gè)app都設(shè)置了一個(gè)硬性的heap size限制,。準(zhǔn)確的heap size限制隨著不同設(shè)備的不同RAM大小而各有差異,。如果你的app已經(jīng)到了heap的限制大小并且再嘗試分配內(nèi)存的話,會(huì)引起OutOfMemoryError的錯(cuò)誤,。

在一些情況下,,你也許想要查詢當(dāng)前設(shè)備的heap size限制大小是多少,然后決定cache的大小,??梢酝ㄟ^getMemoryClass()來查詢。這個(gè)方法會(huì)返回一個(gè)整數(shù),,表明你的app heap size限制是多少megabates,。

4)切換應(yīng)用

當(dāng)用戶在不同應(yīng)用之間進(jìn)行切換的時(shí)候,不是使用交換空間的辦法,。Android會(huì)把那些不包含foreground組件的進(jìn)程放到LRU cache中,。例如,,當(dāng)用戶剛開始啟動(dòng)了一個(gè)應(yīng)用,,這個(gè)時(shí)候?yàn)樗鼊?chuàng)建了一個(gè)進(jìn)程,但是當(dāng)用戶離開這個(gè)應(yīng)用,,這個(gè)進(jìn)程并沒有離開,。系統(tǒng)會(huì)把這個(gè)進(jìn)程放到cache中,,如果用戶后來回到這個(gè)應(yīng)用,這個(gè)進(jìn)程能夠被resued,,從而實(shí)現(xiàn)app的快速切換,。

如果你的應(yīng)用有一個(gè)被緩存的進(jìn)程,它被保留在內(nèi)存中,,并且當(dāng)前不再需要它了,,這會(huì)對(duì)系統(tǒng)的整個(gè)性能有影響。因此當(dāng)系統(tǒng)開始進(jìn)入低內(nèi)存狀態(tài)時(shí),,它會(huì)由系統(tǒng)根據(jù)LRU的規(guī)則與其他因素選擇殺掉某些進(jìn)程,,為了保持你的進(jìn)程能夠盡可能長久的被cached,請(qǐng)參考下面的章節(jié)學(xué)習(xí)何時(shí)釋放你的引用,。

更對(duì)關(guān)于不在foreground的進(jìn)程是Android是如何決定kill掉哪一類進(jìn)程的問題,,請(qǐng)參考Processes and Threads.

第2部分:你的應(yīng)用該如何管理內(nèi)存

你應(yīng)該在開發(fā)過程的每一個(gè)階段都考慮到RAM的有限性,甚至包括在開發(fā)開始之前的設(shè)計(jì)階段。有許多種設(shè)計(jì)與實(shí)現(xiàn)方式,,他們有著不同的效率,,盡管是對(duì)同樣一種技術(shù)的不斷組合與演變。

為了使得你的應(yīng)用效率更高,,你應(yīng)該在設(shè)計(jì)與實(shí)現(xiàn)代碼時(shí),,遵循下面的技術(shù)要點(diǎn)。

1)珍惜Services資源

如果你的app需要在后臺(tái)使用service,,除非它被觸發(fā)執(zhí)行一個(gè)任務(wù),,否則其他時(shí)候都應(yīng)該是非運(yùn)行狀態(tài)。同樣需要注意當(dāng)這個(gè)service已經(jīng)完成任務(wù)后停止service失敗引起的泄漏,。

當(dāng)你啟動(dòng)一個(gè)service,,系統(tǒng)會(huì)傾向?yàn)榱诉@個(gè)Service而一直保留它的Process。這使得process的運(yùn)行代價(jià)很高,,因?yàn)橄到y(tǒng)沒有辦法把Service所占用的RAM讓給其他組件或者被Paged out,。這減少了系統(tǒng)能夠存放到LRU緩存當(dāng)中的process數(shù)量,它會(huì)影響app之間的切換效率,。它甚至?xí)?dǎo)致系統(tǒng)內(nèi)存使用不穩(wěn)定,,從而無法繼續(xù)Hold住 所有目前正在運(yùn)行的Service。

限制你的service的最好辦法是使用IntentService, 它會(huì)在處理完扔給它的intent任務(wù)之后盡快結(jié)束自己,。更多信息,,請(qǐng)閱讀Running in a Background Service.

當(dāng)一個(gè)service已經(jīng)不需要的時(shí)候還繼續(xù)保留它,這對(duì)Android應(yīng)用的內(nèi)存管理來說是最糟糕的錯(cuò)誤之一,。因此千萬不要貪婪的使得一個(gè)Service持續(xù)保留,。不僅僅是因?yàn)樗鼤?huì)使得你的app因RAM的限制而性能糟糕,而且用戶會(huì)發(fā)現(xiàn)那些行為奇怪的app并且卸載它,。

2)當(dāng)你的UI隱藏時(shí)釋放內(nèi)存

當(dāng)用戶切換到其它app并且你的app UI不再可見時(shí),,你應(yīng)該釋放你的UI上占用的任何資源。在這個(gè)時(shí)候釋放UI資源可以顯著的增加系統(tǒng)cached process的能力,,它會(huì)對(duì)用戶的質(zhì)量體驗(yàn)有著直接的影響,。

為了能夠接收到用戶離開你的UI時(shí)的通知,你需要實(shí)現(xiàn)Activtiy類里面的onTrimMemory())回調(diào)方法,。你應(yīng)該使用這個(gè)方法來監(jiān)聽到TRIM_MEMORY_UI_HIDDEN級(jí)別, 它意味著你的UI已經(jīng)隱藏,,你應(yīng)該釋放那些僅僅被你的UI使用的資源。

請(qǐng)注意:你的app僅僅會(huì)在所有UI組件的被隱藏的時(shí)候接收到onTrimMemory()的回調(diào)并帶有參數(shù)TRIM_MEMORY_UI_HIDDEN,。這與onStop()的回調(diào)是不同的,onStop會(huì)在activity的實(shí)例隱藏時(shí)會(huì)執(zhí)行,,例如當(dāng)用戶從你的app的某個(gè)activity跳轉(zhuǎn)到另外一個(gè)activity時(shí)onStop會(huì)被執(zhí)行,。因此你應(yīng)該實(shí)現(xiàn)onStop回調(diào),并且在此回調(diào)里面釋放activity的資源,例如網(wǎng)絡(luò)連接,,unregister廣播接收者,。除非接收到onTrimMemory(TRIM_MEMORY_UI_HIDDEN))的回調(diào),否者你不應(yīng)該釋放你的UI資源,。這確保了用戶從其他activity切回來時(shí),,你的UI資源仍然可用,并且可以迅速恢復(fù)activity,。

3)當(dāng)內(nèi)存緊張時(shí)釋放部分內(nèi)存

在你的app生命周期的任何階段,,onTrimMemory回調(diào)方法同樣可以告訴你整個(gè)設(shè)備的內(nèi)存資源已經(jīng)開始緊張。你應(yīng)該根據(jù)onTrimMemory方法中的內(nèi)存級(jí)別來進(jìn)一步?jīng)Q定釋放哪些資源,。

  • TRIM_MEMORY_RUNNING_MODERATE:你的app正在運(yùn)行并且不會(huì)被列為可殺死的,。但是設(shè)備正運(yùn)行于低內(nèi)存狀態(tài)下,系統(tǒng)開始開始激活殺死LRU Cache中的Process的機(jī)制,。
  • TRIM_MEMORY_RUNNING_LOW:你的app正在運(yùn)行且沒有被列為可殺死的,。但是設(shè)備正運(yùn)行于更低內(nèi)存的狀態(tài)下,你應(yīng)該釋放不用的資源用來提升系統(tǒng)性能,,這會(huì)直接影響了你的app的性能,。
  • TRIM_MEMORY_RUNNING_CRITICAL:你的app仍在運(yùn)行,但是系統(tǒng)已經(jīng)把LRU Cache中的大多數(shù)進(jìn)程都已經(jīng)殺死,,因此你應(yīng)該立即釋放所有非必須的資源,。如果系統(tǒng)不能回收到足夠的RAM數(shù)量,系統(tǒng)將會(huì)清除所有的LRU緩存中的進(jìn)程,,并且開始?xì)⑺滥切┲氨徽J(rèn)為不應(yīng)該殺死的進(jìn)程,,例如那個(gè)進(jìn)程包含了一個(gè)運(yùn)行中的Service。

同樣,,當(dāng)你的app進(jìn)程正在被cached時(shí),,你可能會(huì)接受到從onTrimMemory()中返回的下面的值之一:

  • TRIM_MEMORY_BACKGROUND: 系統(tǒng)正運(yùn)行于低內(nèi)存狀態(tài)并且你的進(jìn)程正處于LRU緩存名單中最不容易殺掉的位置。盡管你的app進(jìn)程并不是處于被殺掉的高危險(xiǎn)狀態(tài),,系統(tǒng)可能已經(jīng)開始?xì)⒌鬖RU緩存中的其他進(jìn)程了,。你應(yīng)該釋放那些容易恢復(fù)的資源,以便于你的進(jìn)程可以保留下來,,這樣當(dāng)用戶回退到你的app的時(shí)候才能夠迅速恢復(fù),。
  • TRIM_MEMORY_MODERATE: 系統(tǒng)正運(yùn)行于低內(nèi)存狀態(tài)并且你的進(jìn)程已經(jīng)已經(jīng)接近LRU名單的中部位置。如果系統(tǒng)開始變得更加內(nèi)存緊張,,你的進(jìn)程是有可能被殺死的,。
  • TRIM_MEMORY_COMPLETE: 系統(tǒng)正運(yùn)行與低內(nèi)存的狀態(tài)并且你的進(jìn)程正處于LRU名單中最容易被殺掉的位置。你應(yīng)該釋放任何不影響你的app恢復(fù)狀態(tài)的資源,。

因?yàn)閛nTrimMemory()的回調(diào)是在API 14才被加進(jìn)來的,,對(duì)于老的版本,,你可以使用onLowMemory)回調(diào)來進(jìn)行兼容。onLowMemory相當(dāng)與TRIM_MEMORY_COMPLETE,。

Note: 當(dāng)系統(tǒng)開始清除LRU緩存中的進(jìn)程時(shí),,盡管它首先按照LRU的順序來操作,但是它同樣會(huì)考慮進(jìn)程的內(nèi)存使用量,。因此消耗越少的進(jìn)程則越容易被留下來,。

4)檢查你應(yīng)該使用多少的內(nèi)存

正如前面提到的,每一個(gè)Android設(shè)備都會(huì)有不同的RAM總大小與可用空間,,因此不同設(shè)備為app提供了不同大小的heap限制,。你可以通過調(diào)用getMemoryClass())來獲取你的app的可用heap大小。如果你的app嘗試申請(qǐng)更多的內(nèi)存,,會(huì)出現(xiàn)OutOfMemory的錯(cuò)誤,。

在一些特殊的情景下,你可以通過在manifest的application標(biāo)簽下添加largeHeap=true的屬性來聲明一個(gè)更大的heap空間,。如果你這樣做,,你可以通過getLargeMemoryClass())來獲取到一個(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í)間更長。在任務(wù)切換時(shí),,系統(tǒng)的性能會(huì)變得大打折扣,。

另外, large heap并不一定能夠獲取到更大的heap。在某些有嚴(yán)格限制的機(jī)器上,,large heap的大小和通常的heap size是一樣的,。因此即使你申請(qǐng)了large heap,你還是應(yīng)該通過執(zhí)行g(shù)etMemoryClass()來檢查實(shí)際獲取到的heap大小,。

5)避免bitmaps的浪費(fèi)

當(dāng)你加載一個(gè)bitmap時(shí),,僅僅需要保留適配當(dāng)前屏幕設(shè)備分辨率的數(shù)據(jù)即可,如果原圖高于你的設(shè)備分辨率,,需要做縮小的動(dòng)作,。請(qǐng)記住,增加bitmap的尺寸會(huì)對(duì)內(nèi)存呈現(xiàn)出2次方的增加,,因?yàn)閄與Y都在增加,。

Note:在Android 2.3.x (API level 10)及其以下, bitmap對(duì)象是的pixel data是存放在native內(nèi)存中的,它不便于調(diào)試,。然而,,從Android 3.0(API level 11)開始,,bitmap pixel data是分配在你的app的Dalvik heap中, 這提升了GC的工作并且更加容易Debug。因此如果你的app使用bitmap并在舊的機(jī)器上引發(fā)了一些內(nèi)存問題,,切換到3.0以上的機(jī)器上進(jìn)行Debug。

6)使用優(yōu)化的數(shù)據(jù)容器

利用Android Framework里面優(yōu)化過的容器類,,例如SparseArray, SparseBooleanArray, 與 LongSparseArray. 通常的HashMap的實(shí)現(xiàn)方式更加消耗內(nèi)存,,因?yàn)樗枰粋€(gè)額外的實(shí)例對(duì)象來記錄Mapping操作。另外,,SparseArray更加高效在于他們避免了對(duì)key與value的autobox自動(dòng)裝箱,,并且避免了裝箱后的解箱。

7)請(qǐng)注意內(nèi)存開銷

對(duì)你所使用的語言與庫的成本與開銷有所了解,,從開始到結(jié)束,,在設(shè)計(jì)你的app時(shí)謹(jǐn)記這些信息。通常,,表面上看起來無關(guān)痛癢(innocuous)的事情也許實(shí)際上會(huì)導(dǎo)致大量的開銷,。例如:

  • Enums的內(nèi)存消耗通常是static constants的2倍。你應(yīng)該盡量避免在Android上使用enums,。
  • 在Java中的每一個(gè)類(包括匿名內(nèi)部類)都會(huì)使用大概500 bytes,。
  • 每一個(gè)類的實(shí)例花銷是12-16 bytes。
  • 往HashMap添加一個(gè)entry需要額一個(gè)額外占用的32 bytes的entry對(duì)象,。

8)請(qǐng)注意代碼“抽象”

通常, 開發(fā)者使用抽象簡單的作為”好的編程實(shí)踐”,因?yàn)槌橄竽軌蛱嵘a的靈活性與可維護(hù)性,。然而,抽象會(huì)導(dǎo)致一個(gè)顯著的開銷:通常他們需要同等量的代碼用于可執(zhí)行,。那些代碼會(huì)被map到內(nèi)存中,。因此如果你的抽象沒有顯著的提升效率,應(yīng)該盡量避免他們,。

9)為序列化的數(shù)據(jù)使用nano protobufs

Protocol buffers是由Google為序列化結(jié)構(gòu)數(shù)據(jù)而設(shè)計(jì)的,,一種語言無關(guān),平臺(tái)無關(guān),,具有良好擴(kuò)展性的協(xié)議,。類似XML,卻比XML更加輕量,,快速,,簡單。如果你需要為你的數(shù)據(jù)實(shí)現(xiàn)協(xié)議化,,你應(yīng)該在客戶端的代碼中總是使用nano protobufs,。通常的協(xié)議化操作會(huì)生成大量繁瑣的代碼,這容易給你的app帶來許多問題:增加RAM的使用量,,顯著增加APK的大小,,更慢的執(zhí)行速度,,更容易達(dá)到DEX的字符限制。

關(guān)于更多細(xì)節(jié),,請(qǐng)參考protobuf readme的”Nano version”章節(jié),。

10)Avoid dependency injection frameworks

使用類似Guice或者RoboGuice等framework injection包是很有效的,因?yàn)樗麄兡軌蚝喕愕拇a,。

RoboGuice 2 smoothes out some of the wrinkles in your Android development experience and makes things simple and fun. Do you always forget to check for null when you getIntent().getExtras()? RoboGuice 2 will help you. Think casting findViewById() to a TextView shouldn’t be necessary? RoboGuice 2 is on it. RoboGuice 2 takes the guesswork out of development. Inject your View, Resource, System Service, or any other object, and let RoboGuice 2 take care of the details.

然而,,那些框架會(huì)通過掃描你的代碼執(zhí)行許多初始化的操作,這會(huì)導(dǎo)致你的代碼需要大量的RAM來map代碼,。但是mapped pages會(huì)長時(shí)間的被保留在RAM中,。

11)謹(jǐn)慎使用external libraries

很多External library的代碼都不是為移動(dòng)網(wǎng)絡(luò)環(huán)境而編寫的,在移動(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的陷阱。如果沒有一個(gè)合適的庫與你的需求相吻合,,你應(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來為layout進(jìn)行優(yōu)化,。同樣還應(yīng)該關(guān)注lint工具所提出的建議,,進(jìn)行優(yōu)化。

13)使用ProGuard來剔除不需要的代碼

ProGuard能夠通過移除不需要的代碼,,重命名類,,域與方法等方對(duì)代碼進(jìn)行壓縮,優(yōu)化與混淆。使用ProGuard可以是的你的代碼更加緊湊,,這樣能夠使用更少mapped代碼所需要的RAM,。

14)對(duì)最終的APK使用zipalign

在編寫完所有代碼,,并通過編譯系統(tǒng)生成APK之后,你需要使用zipalign對(duì)APK進(jìn)行重新校準(zhǔn),。如果你不做這個(gè)步驟,,會(huì)導(dǎo)致你的APK需要更多的RAM,因?yàn)橐恍╊愃茍D片資源的東西不能被mapped,。

Notes::Google Play不接受沒有經(jīng)過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)存使用:通過把你的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è)可以長時(shí)間后臺(tái)播放的Music Player,。如果整個(gè)app運(yùn)行在一個(gè)進(jìn)程中,當(dāng)后臺(tái)播放的時(shí)候,,前臺(tái)的那些UI資源也沒有辦法得到釋放,。類似這樣的app可以切分成2個(gè)進(jìn)程:一個(gè)用來操作UI,另外一個(gè)用來后臺(tái)的Service.

你可以通過在manifest文件中聲明’android:process’屬性來實(shí)現(xiàn)某個(gè)組件運(yùn)行在另外一個(gè)進(jìn)程的操作,。

1
2
<service android:name=".PlaybackService"
         android:process=":background" />

更多關(guān)于使用這個(gè)技術(shù)的細(xì)節(jié),,請(qǐng)參考原文,鏈接如下,。


文章學(xué)習(xí)自http://developer./training/articles/memory.html 轉(zhuǎn)載請(qǐng)注明出自http://kesenhoo.github.com,,謝謝

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多