1. 為什么需要性能優(yōu)化? 上面說到,在時間窗口期內(nèi)開發(fā)出產(chǎn)品是極端重要的,但是雖然基本功能我們實現(xiàn)了,但是開發(fā)出來的產(chǎn)品代碼運行的效率怎么樣呢?我們的App用戶給用戶的體驗如何呢? 我們的App在低端機(jī)上經(jīng)常ANR、閃退、卡頓等 我們的App在其他分辨率上顯示慘不忍睹? 我們的App在不同網(wǎng)絡(luò)的情況下如何處理的?
我們的App體驗如此之差,導(dǎo)致大量的用戶流失。這些迫使我們認(rèn)識到性能優(yōu)化是非常重要,某種程度上甚至超過了新功能的開發(fā)。
2性能優(yōu)化四個方面: - 響應(yīng)時間(Response Time) - 界面卡頓(ANR) - 耗內(nèi)存(Memory) - 內(nèi)存泄露(Out of memory)
響應(yīng)時間 1)HTTP請求方式 這里指的是客戶端與服務(wù)端交互,拿到數(shù)據(jù)、解析、再到顯示到界面整個過程耗費的時間。 這個部分涉及客戶端的優(yōu)化,也涉及服務(wù)端的優(yōu)化,這里只討論客戶端。
使用優(yōu)秀的開源Http框架是我們比較好的選擇,它的優(yōu)點是經(jīng)過市場的驗證. 加快響應(yīng)速度(網(wǎng)絡(luò)請求框架)。
2)數(shù)據(jù)解析 實際開發(fā)當(dāng)中服務(wù)端的返回數(shù)據(jù)格式無非就兩種: - JSON - XML 在Android中均可以使用優(yōu)秀的解析庫來加快我們的解析速度,XML中有dom4j,JSON有Jackson、Gson,我們通過這些庫實現(xiàn)我們更快的完成數(shù)據(jù)解析,提高我們的開發(fā)效率。
3)數(shù)據(jù)存儲 為了提高應(yīng)用程序的響應(yīng)時間,數(shù)據(jù)緩存是一個比較好的方式,我們可以預(yù)處理服務(wù)器返回的數(shù)據(jù),對數(shù)據(jù)進(jìn)行緩存刷新。
優(yōu)化點: - 異步請求網(wǎng)絡(luò)數(shù)據(jù) - 預(yù)處理服務(wù)器返回數(shù)據(jù) - 異步進(jìn)行數(shù)據(jù)存儲操作 - 數(shù)據(jù)緩存刷新 - Timeout超時重試 - 在主線程中操作UI
界面卡頓 ANR表示”應(yīng)用程序無響應(yīng)”,這個是需要我們避免發(fā)生的事情,出現(xiàn)這個異常的原因: - 主線程 (“事件處理線程” / “UI線程”) 在5秒內(nèi)沒有響應(yīng)輸入事件 - BroadcastReceiver在10秒內(nèi)沒有執(zhí)行完畢
導(dǎo)致ANR的原因有很多,一般情況就是在UI線程做了耗時的操作,例如”網(wǎng)絡(luò)請求”、數(shù)據(jù)庫操作。
那么如何避免? - UI線程只做界面刷新,不做任何耗時操作,耗時操作放在子線程來做 - 可以使用Thread+handle或者AsyncTask來進(jìn)行邏輯處理
耗內(nèi)存 每部手機(jī)的內(nèi)存有限,我們這里所說的內(nèi)存指的是手機(jī)的RAM,它是Ramdom Access Memory的縮寫,我們應(yīng)用程序的需要隨機(jī)讀寫的數(shù)據(jù)就存在RAM中,android手機(jī)之所以會比較耗內(nèi)存,這跟Android后臺的處理有關(guān),我們知道Android應(yīng)用是使用Java開發(fā)的,運行Java需要有虛擬機(jī),說明每開啟一個應(yīng)用都會創(chuàng)建一個虛擬機(jī),而這是需要內(nèi)存的,所以我們開的應(yīng)用越多,后臺進(jìn)程越多,內(nèi)存都分配出去了,才導(dǎo)致內(nèi)存消耗的嚴(yán)重。 隨機(jī)存取存儲器(random access memory,RAM)又稱作"隨機(jī)存儲器",是與CPU直接交換數(shù)據(jù)的內(nèi)部存儲器,也叫主存(內(nèi)存)。它可以隨時讀寫,而且速度很快,通常作為操作系統(tǒng)或其他正在運行中的程序的臨時數(shù)據(jù)存儲媒介。 其實這個問題我們是沒得破的,只要內(nèi)存不夠,我們的應(yīng)用還是會卡。我們開發(fā)的應(yīng)用依賴與系統(tǒng)給我們分配的堆內(nèi)存,一般上限在16M~48M,但我們可以通過在AndroidManifest設(shè)置Application屬性largeHeap=“true”來申請更多的堆內(nèi)存。 可以通過代碼獲取可用堆內(nèi)存限制
內(nèi)存泄露 內(nèi)存泄露這個問題已經(jīng)被說爛了,大家都知道有內(nèi)存泄露這個問題存在,但為什么會發(fā)生內(nèi)存泄露? 這里的內(nèi)存泄露并不是真正意思上的泄露,而是因為內(nèi)存不足不能進(jìn)行GC操作,從而導(dǎo)致占用內(nèi)存過大,拋出out of memory異常,而被系統(tǒng)Kill掉。(內(nèi)存泄露進(jìn)而導(dǎo)致內(nèi)存溢出)
3,如何進(jìn)行性能優(yōu)化? 前面講了一些背景知識,對我們理解內(nèi)存優(yōu)化有一定的幫助,下面就簡單說一下我們優(yōu)化的方向: - 布局優(yōu)化 - 內(nèi)存優(yōu)化
布局優(yōu)化 優(yōu)化點: - 避免OverDraw - 優(yōu)化布局層級 - 避免過多無用嵌套 - 使用標(biāo)簽 重用layout - 使用延遲加載 - Hierarchy View進(jìn)行層級分析
內(nèi)存優(yōu)化 內(nèi)存優(yōu)化的點有很多,這里我主要分為兩大塊: - Bitmap優(yōu)化 - 代碼優(yōu)化
代碼優(yōu)化 關(guān)于代碼這個就有的說了,任何能改進(jìn)我們程序的優(yōu)化點都能寫在這里,這里沒辦法把所有優(yōu)化的點列在這里,只提供相關(guān)的參考,剩下的就好各位經(jīng)驗總結(jié)和積累了。 優(yōu)化點: - 對常量使用static修飾符 - 使用靜態(tài)方法 - 減少不必要的成員變量 - 盡量不要使用枚舉,少用迭代器 - 對Cursor、Receiver、Sensor、File等對象,要注意它們的創(chuàng)建、回收與注冊、反注冊 - 避免大量使用注解、反射 - 使用RenderScript、OpenGL來進(jìn)行復(fù)雜的繪圖操作 - 使用SurfaceView來替代View進(jìn)行大量、頻繁的繪圖操作 - 盡量使用視圖緩存,而不是每次都執(zhí)行inflate()方法解析視圖
創(chuàng)建新的對象都需要額外的內(nèi)存空間,要盡量減少創(chuàng)建新的對象。 將類、變量、方法等等的可見性修改為最小。 針對字符串的拼接,使用StringBuffer替代String。 不要在循環(huán)當(dāng)中聲明臨時變量,不要在循環(huán)中捕獲異常。 如果對于線程安全沒有要求,盡量使用線程不安全的集合對象。 使用集合對象,如果事先知道其大小,則可以在構(gòu)造方法中設(shè)置初始大小。 文件讀取操作需要使用緩存類,及時關(guān)閉文件。 慎用異常,使用異常會導(dǎo)致性能降低。 如果程序會頻繁創(chuàng)建線程,則可以考慮使用線程池。
以上都是些經(jīng)驗總結(jié),大致都相差無幾,朋友們在做代碼優(yōu)化的時候,可以根據(jù)這些優(yōu)化點,有針對性去重構(gòu)代碼,其實最重要還是代碼的可讀性,結(jié)構(gòu)清晰。
性能優(yōu)化工具
Memory Monitor - 內(nèi)存監(jiān)視工具 TraceView MAT Android開發(fā)者對與以上幾個性能調(diào)優(yōu)的工具一定不陌生,這里我也不再寫那么多廢話了,關(guān)于它們的使用方法,官網(wǎng)還有一些大牛的博客都有介紹。
寫這篇文章的出發(fā)點也是對Android性能優(yōu)化有個比較清楚的認(rèn)識,任何事情都不可能一蹴而就,需要循循漸進(jìn),對一個初學(xué)者你談優(yōu)化很不現(xiàn)實,我們先把基本的做好,再去考慮相應(yīng)的優(yōu)化,筆者也在不斷學(xué)習(xí)當(dāng)中,借鑒別人好的優(yōu)化方案,提高產(chǎn)品的質(zhì)量,感謝大家對筆者的關(guān)注。
性能優(yōu)化技術(shù),簡而言之,就是提高我們程序的性能,讓我們的應(yīng)用更快,更少使用CPU資源,更少使用內(nèi)存。 性能優(yōu)化,一方面需要自身能力的提高,另外一方面,也需要有意識去學(xué)習(xí)優(yōu)化技術(shù),并應(yīng)用于自身項目的開發(fā)中。 |
|