掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
性能優(yōu)化是一個大的范疇,如果有人問你在Android中如何做性能優(yōu)化的,也許都不知道從哪開始說起。首先要明白的是,為什么我們的App需要優(yōu)化,最顯而易見的時刻:用戶say,什么狗屎,刷這么久都沒反應(yīng),取關(guān)卸載算了。

這跟什么有關(guān),我們先蒼白的反駁下,尼瑪用戶設(shè)備老舊網(wǎng)又爛,關(guān)我屁事,根本不用優(yōu)化??墒?,老板拍板了,施壓給CTO,然后CTO又來找你:Y的今天必須給我想辦法優(yōu)化了,不然不準(zhǔn)回家。
好吧,為什么從UI的表象上看,App又卡又慢而且還錯亂。我們試著來剖析下吧。
題外話:把minSDK改到4.0+,去特么的low用戶,連手機(jī)都不愿意換,還能指望它能給你帶來多少營收么,直接pass掉吧。4.0前的系統(tǒng)bug不少,不能為了彌補(bǔ)這些bug而降低了整體的高性能。
好了,讓我們先從UI說起:
首先要明白的是UI的繪制流程:measure-layout-draw,measure與layout都需要for loop所有的子控件,匯集起來才能完成繪制,布局。所以子控件越多,所消耗的時間越長(inflate,layout_weight,relative,多層嵌套等),減少不必要的子控件或?qū)蛹?,是相?dāng)有必要的。你可以通過merge,viewstub這些標(biāo)簽來減少層級嵌套。如果你的空間觀念沒那么好,可以用HierarchyViewer工具來檢查。
對于Listview或者GridView這種多item的組件來說,復(fù)用item可以減少inflate次數(shù),通過setTag,getTag的ViewHolder方式實現(xiàn)復(fù)用,這里要注意的是,holder中的控件最好reset后再賦值,避免圖片,文字錯亂。
對于ViewPager第一次顯示時卡頓以及左右滑動卡頓,有以下幾種優(yōu)化方式:
圖片顯示不出來或者加載時間太長,怎么辦?分兩部分,下載速度,加載速度。
對于下載,要控制好同時下載的最大任務(wù)數(shù)(平均速度慢),同時給InputStream再包一層緩沖流會更快(如BufferedInputStream)。
對于加載速度,我們要知道一點(diǎn),雖然下載的圖片可能只有幾百K,但是decode 成bitmap所占用的內(nèi)存可是成倍的,盡可能的減小圖片size是根本因素,讓服務(wù)端提供不同分辨率的圖片才是最好的解決方案,內(nèi)存總有耗盡的時刻,別老想著大分辨率會更清晰,實際就只有150*150的空間,非給弄張1000*1000的圖片是不恰當(dāng)?shù)摹A硗庹摷虞d速度:內(nèi)存>硬盤>網(wǎng)絡(luò),合理的使用內(nèi)存緩存也是關(guān)鍵。假如自己寫不好,沒關(guān)系,有那么多開源的圖片緩存框架,不用自己操心。
再說緩存
有很多種緩存方式,也不用Stay列舉了,我們要說的是搭配使用。
比方說,以前我們一直在用強(qiáng)引用,HashMap,后來我們發(fā)現(xiàn)占內(nèi)存,我們就用軟引用,弱引用來及時回收,再后來因為回收機(jī)制不可控,所以又有了 lrucache,disklrucache通過算法來平衡內(nèi)存與硬盤緩存。隨著android版本的推進(jìn)與演化,我們也應(yīng)該擁抱變化。如果你的App里還有軟引用,弱引用的地方,不妨再check下。
比方說網(wǎng)絡(luò)+數(shù)據(jù)庫。網(wǎng)絡(luò)我們一般都是去主動獲取,而非被動接受。那如果說數(shù)據(jù)是重復(fù)的或者未更改的呢?那我們?nèi)ト∫淮尉W(wǎng)絡(luò)數(shù)據(jù)有什么意義呢?我的解決方案是給每個activity或 fragment或每個組件設(shè)置一個最大請求間隔,比如一個listview,第一次請求數(shù)據(jù)時,保存一份到數(shù)據(jù)庫,并記下時間戳,當(dāng)下次重新初始化時,判斷是否超過最大時間間隔(如5分鐘),如果沒有,只加載數(shù)據(jù)庫數(shù)據(jù),不需要再做網(wǎng)絡(luò)請求。當(dāng)然,還有一些隱式的http請求框架會緩存服務(wù)器數(shù)據(jù),在一定時間內(nèi)不再請求網(wǎng)絡(luò),或者當(dāng)服務(wù)器返回304時將之前緩存的數(shù)據(jù)直接返回。
反正也說到網(wǎng)絡(luò)了,那我們也來說說
現(xiàn)在有很多現(xiàn)成HTTP框架供我們使用,我們幾乎只用寫配置就可以搞定一個url請求,但是這里有很多需要服務(wù)端配合的,比如:json數(shù)據(jù)格式,WebP代替jpg,支持?jǐn)帱c(diǎn)續(xù)傳,多個請求合并成一個,盡量不做重定向,服務(wù)器緩存以及負(fù)載均衡等。
對客戶端本身,除了上述的實現(xiàn),我們還需要合理的緩存,控制最大請求并發(fā)量,及時取消已失效的請求,過濾重復(fù)請求,timeout時間設(shè)置,請求優(yōu)先級設(shè)置等。
優(yōu)化可不是一個人的事,實現(xiàn)一個功能簡單,但是想優(yōu)化重構(gòu),那是很不容易的事。需要多方面的預(yù)判與聯(lián)調(diào)。合理的假設(shè)與實踐是優(yōu)化最重要的手段。
說完這些具體的點(diǎn),我們再來說說一些常識,或者稱之為代碼規(guī)范。
當(dāng)然還有很多很多,Stay所說的也只是一個大的輪廓,還是需要自己不斷的嘗試。會開發(fā)寫代碼跟會做產(chǎn)品的區(qū)別還是蠻大的,僅僅是態(tài)度就能刷死80%的碼農(nóng)了。當(dāng)你碰到一些需要優(yōu)化的地方,耐心的去分析,時間的累積會讓你成為真正的工程師。
另外優(yōu)化也沒有絕對的完美,每一次優(yōu)化都是基于當(dāng)前的環(huán)境來做的,要明白溝通是最好的優(yōu)化,不盲從,不隨便,三思而后行。
Android上如何做性能優(yōu)化的?大概寫三年代碼就能差不多知道了。
原文鏈接:http://www.cnblogs.com/stay/p/4784014.html

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流